2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="2.1.21" />
|
||||
<option name="version" value="2.2.0" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -98,6 +98,10 @@ allprojects {
|
||||
|
||||
// Uncomment to suppress Compose Kotlin compiler compatibility warning
|
||||
// freeCompilerArgs.addAll(listOf("-P", "plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true"))
|
||||
|
||||
// Fix compilation warning for annotations
|
||||
// See https://youtrack.jetbrains.com/issue/KT-73255/Change-defaulting-rule-for-annotations for more details
|
||||
freeCompilerArgs.add("-Xannotation-default-target=first-only")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ private fun MessagesViewContent(
|
||||
|
||||
Box {
|
||||
val scrollBehavior = PinnedMessagesBannerViewDefaults.rememberScrollBehavior(
|
||||
pinnedMessagesCount = state.pinnedMessagesBannerState.pinnedMessagesCount(),
|
||||
pinnedMessagesCount = (state.pinnedMessagesBannerState as? PinnedMessagesBannerState.Visible)?.pinnedMessagesCount() ?: 0,
|
||||
)
|
||||
TimelineView(
|
||||
state = state.timelineState,
|
||||
|
||||
@@ -10,14 +10,31 @@ package io.element.android.features.messages.impl.pinned.banner
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import io.element.android.libraries.designsystem.text.toAnnotatedString
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Immutable
|
||||
sealed interface PinnedMessagesBannerState {
|
||||
data object Hidden : PinnedMessagesBannerState
|
||||
sealed interface Visible : PinnedMessagesBannerState
|
||||
@Immutable
|
||||
sealed interface Visible : PinnedMessagesBannerState {
|
||||
fun pinnedMessagesCount() = when (this) {
|
||||
is Loading -> expectedPinnedMessagesCount
|
||||
is Loaded -> loadedPinnedMessagesCount
|
||||
}
|
||||
|
||||
fun currentPinnedMessageIndex() = when (this) {
|
||||
is Loading -> expectedPinnedMessagesCount - 1
|
||||
is Loaded -> currentPinnedMessageIndex
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun formattedMessage() = when (this) {
|
||||
is Loading -> stringResource(id = CommonStrings.screen_room_pinned_banner_loading_description).toAnnotatedString()
|
||||
is Loaded -> currentPinnedMessage.formatted
|
||||
}
|
||||
}
|
||||
|
||||
data class Loading(val expectedPinnedMessagesCount: Int) : Visible
|
||||
data class Loaded(
|
||||
val currentPinnedMessage: PinnedMessagesBannerItem,
|
||||
@@ -25,23 +42,4 @@ sealed interface PinnedMessagesBannerState {
|
||||
val loadedPinnedMessagesCount: Int,
|
||||
val eventSink: (PinnedMessagesBannerEvents) -> Unit
|
||||
) : Visible
|
||||
|
||||
fun pinnedMessagesCount() = when (this) {
|
||||
is Hidden -> 0
|
||||
is Loading -> expectedPinnedMessagesCount
|
||||
is Loaded -> loadedPinnedMessagesCount
|
||||
}
|
||||
|
||||
fun currentPinnedMessageIndex() = when (this) {
|
||||
is Hidden -> 0
|
||||
is Loading -> expectedPinnedMessagesCount - 1
|
||||
is Loaded -> currentPinnedMessageIndex
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun formattedMessage() = when (this) {
|
||||
is Hidden -> AnnotatedString("")
|
||||
is Loading -> stringResource(id = CommonStrings.screen_room_pinned_banner_loading_description).toAnnotatedString()
|
||||
is Loaded -> currentPinnedMessage.formatted
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ fun PinnedMessagesBannerView(
|
||||
|
||||
@Composable
|
||||
private fun PinnedMessagesBannerRow(
|
||||
state: PinnedMessagesBannerState,
|
||||
state: PinnedMessagesBannerState.Visible,
|
||||
onClick: (EventId) -> Unit,
|
||||
onViewAllClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.impl.attachments
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.messages.impl.attachments.preview.SendActionState
|
||||
import io.element.android.features.messages.impl.attachments.preview.aMediaUploadInfo
|
||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||
import org.junit.Test
|
||||
|
||||
class SendActionStateTest {
|
||||
@Test
|
||||
fun `mediaUploadInfo() should return the value from Uploading class`() {
|
||||
val mediaUploadInfo: MediaUploadInfo = aMediaUploadInfo()
|
||||
val state: SendActionState = SendActionState.Sending.Uploading(
|
||||
progress = 0.5f,
|
||||
mediaUploadInfo = aMediaUploadInfo()
|
||||
)
|
||||
assertThat(state.mediaUploadInfo()).isEqualTo(mediaUploadInfo)
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class PinnedMessagesBannerPresenterTest {
|
||||
val presenter = createPinnedMessagesBannerPresenter(room = room)
|
||||
presenter.test {
|
||||
skipItems(2)
|
||||
val loadingState = awaitItem()
|
||||
val loadingState = awaitItem() as PinnedMessagesBannerState.Loading
|
||||
assertThat(loadingState).isEqualTo(PinnedMessagesBannerState.Loading(1))
|
||||
assertThat(loadingState.pinnedMessagesCount()).isEqualTo(1)
|
||||
assertThat(loadingState.currentPinnedMessageIndex()).isEqualTo(0)
|
||||
@@ -167,7 +167,8 @@ class PinnedMessagesBannerPresenterTest {
|
||||
val presenter = createPinnedMessagesBannerPresenter(room = room)
|
||||
presenter.test {
|
||||
skipItems(2)
|
||||
awaitItem().also { loadingState ->
|
||||
awaitItem().also { state ->
|
||||
val loadingState = state as PinnedMessagesBannerState.Loading
|
||||
assertThat(loadingState).isEqualTo(PinnedMessagesBannerState.Loading(1))
|
||||
assertThat(loadingState.pinnedMessagesCount()).isEqualTo(1)
|
||||
assertThat(loadingState.currentPinnedMessageIndex()).isEqualTo(0)
|
||||
|
||||
@@ -40,7 +40,7 @@ signing.element.nightly.keyPassword=Secret
|
||||
|
||||
# Customise the Lint version to use a more recent version than the one bundled with AGP
|
||||
# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html
|
||||
android.experimental.lint.version=8.11.0
|
||||
android.experimental.lint.version=8.12.0-alpha07
|
||||
|
||||
# Enable test fixture for all modules by default
|
||||
android.experimental.enableTestFixtures=true
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
[versions]
|
||||
# Project
|
||||
android_gradle_plugin = "8.11.0"
|
||||
kotlin = "2.1.21"
|
||||
kotlin = "2.2.0"
|
||||
kotlinpoet = "2.2.0"
|
||||
ksp = "2.1.21-2.0.2"
|
||||
ksp = "2.2.0-2.0.2"
|
||||
firebaseAppDistribution = "5.1.1"
|
||||
|
||||
# AndroidX
|
||||
@@ -33,8 +33,8 @@ accompanist = "0.37.3"
|
||||
test_core = "1.6.1"
|
||||
|
||||
# Jetbrain
|
||||
datetime = "0.6.2"
|
||||
serialization_json = "1.8.1"
|
||||
datetime = "0.7.0"
|
||||
serialization_json = "1.9.0"
|
||||
|
||||
#other
|
||||
detekt = "1.23.8"
|
||||
|
||||
@@ -22,6 +22,14 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
optIn = listOf(
|
||||
"kotlin.time.ExperimentalTime"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.dagger)
|
||||
implementation(projects.libraries.core)
|
||||
|
||||
@@ -33,8 +33,8 @@ class DefaultDateFormatterDay @Inject constructor(
|
||||
return if (useRelative) {
|
||||
val dayDiff = today.date.toEpochDays() - dateToFormat.date.toEpochDays()
|
||||
when (dayDiff) {
|
||||
0 -> dateFormatters.getRelativeDay(timestamp, "Today")
|
||||
1 -> dateFormatters.getRelativeDay(timestamp, "Yesterday")
|
||||
0L -> dateFormatters.getRelativeDay(timestamp, "Today")
|
||||
1L -> dateFormatters.getRelativeDay(timestamp, "Yesterday")
|
||||
else -> if (dayDiff < 7) {
|
||||
dateFormatters.formatDateWithDay(dateToFormat)
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,6 @@ package io.element.android.libraries.dateformatter.impl
|
||||
import android.text.format.DateUtils
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.datetime.toJavaLocalDate
|
||||
@@ -20,6 +19,7 @@ import java.time.Period
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.time.Clock
|
||||
|
||||
@SingleIn(AppScope::class)
|
||||
class DateFormatters @Inject constructor(
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
package io.element.android.libraries.dateformatter.impl
|
||||
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
class LocalDateTimeProvider @Inject constructor(
|
||||
private val clock: Clock,
|
||||
|
||||
@@ -12,9 +12,9 @@ import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.element.android.libraries.dateformatter.impl.TimezoneProvider
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.util.Locale
|
||||
import kotlin.time.Clock
|
||||
|
||||
@Module
|
||||
@ContributesTo(AppScope::class)
|
||||
|
||||
@@ -28,7 +28,7 @@ import io.element.android.libraries.dateformatter.impl.DefaultDateFormatter
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.allBooleans
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.time.Instant
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
|
||||
@@ -16,9 +16,9 @@ import io.element.android.libraries.dateformatter.impl.DateFormatters
|
||||
import io.element.android.libraries.dateformatter.impl.DefaultDateFormatter
|
||||
import io.element.android.libraries.dateformatter.impl.DefaultDateFormatterDay
|
||||
import io.element.android.libraries.dateformatter.impl.LocalDateTimeProvider
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.util.Locale
|
||||
import kotlin.time.Instant
|
||||
|
||||
/**
|
||||
* Create DefaultDateFormatter and set current time to the provided date.
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
package io.element.android.libraries.dateformatter.impl.previews
|
||||
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
class PreviewClock : Clock {
|
||||
private var instant: Instant = Instant.fromEpochMilliseconds(0)
|
||||
|
||||
@@ -11,10 +11,10 @@ import android.os.Build
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.dateformatter.api.DateFormatterMode
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.time.Instant
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@Config(qualifiers = "fr", sdk = [Build.VERSION_CODES.TIRAMISU])
|
||||
|
||||
@@ -11,10 +11,10 @@ import android.os.Build
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.dateformatter.api.DateFormatterMode
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.time.Instant
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@Config(qualifiers = "en", sdk = [Build.VERSION_CODES.TIRAMISU])
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
package io.element.android.libraries.dateformatter.impl
|
||||
|
||||
import io.element.android.tests.testutils.InstrumentationStringProvider
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.util.Locale
|
||||
import kotlin.time.Instant
|
||||
|
||||
/**
|
||||
* Create DefaultDateFormatter and set current time to the provided date.
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
package io.element.android.libraries.dateformatter.impl
|
||||
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
class FakeClock : Clock {
|
||||
private var instant: Instant = Instant.fromEpochMilliseconds(0)
|
||||
|
||||
@@ -13,8 +13,10 @@ plugins {
|
||||
android {
|
||||
namespace = "io.element.android.libraries.maplibre.compose"
|
||||
|
||||
kotlinOptions {
|
||||
freeCompilerArgs += "-Xexplicit-api=strict"
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
explicitApi()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user