From be2753161b82adf2af9dd03de068a65996190644 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:40:57 +0000 Subject: [PATCH 01/73] fix(deps): update dependency io.mockk:mockk to v1.14.6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0610715fdc..9b83c48d7a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -149,7 +149,7 @@ test_corektx = { module = "androidx.test:core-ktx", version.ref = "test_core" } test_arch_core = "androidx.arch.core:core-testing:2.2.0" test_junit = "junit:junit:4.13.2" test_runner = "androidx.test:runner:1.7.0" -test_mockk = "io.mockk:mockk:1.14.5" +test_mockk = "io.mockk:mockk:1.14.6" test_konsist = "com.lemonappdev:konsist:0.17.3" test_turbine = "app.cash.turbine:turbine:1.2.1" test_truth = "com.google.truth:truth:1.4.5" From 0d4e2dd2fba6c65dc5cbff4e54fa7744b20f9de9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 2 Oct 2025 16:15:33 +0200 Subject: [PATCH 02/73] feature(space) : ensure RoomSummaryRow can display space invites --- .../features/home/impl/components/RoomSummaryRow.kt | 12 ++++++++---- .../impl/datasource/RoomListRoomSummaryFactory.kt | 1 + .../features/home/impl/model/RoomListRoomSummary.kt | 1 + .../home/impl/model/RoomListRoomSummaryProvider.kt | 11 +++++++++++ .../home/impl/model/RoomListBaseRoomSummaryTest.kt | 2 ++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt index 3036865eea..c5e1798baa 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt @@ -189,10 +189,14 @@ private fun RoomSummaryScaffoldRow( ) { Avatar( avatarData = room.avatarData, - avatarType = AvatarType.Room( - heroes = room.heroes, - isTombstoned = room.isTombstoned, - ), + avatarType = if (room.isSpace) { + AvatarType.Space(isTombstoned = room.isTombstoned) + } else { + AvatarType.Room( + heroes = room.heroes, + isTombstoned = room.isTombstoned, + ) + }, hideImage = hideAvatarImage, ) Spacer(modifier = Modifier.width(16.dp)) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt index b6f908fd5d..ffd6f640ac 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt @@ -69,6 +69,7 @@ class RoomListRoomSummaryFactory( user.getAvatarData(size = AvatarSize.RoomListItem) }.toImmutableList(), isTombstoned = roomInfo.successorRoom != null, + isSpace = roomInfo.isSpace, ) } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt index 3f166a66b4..8af359d3e5 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt @@ -38,6 +38,7 @@ data class RoomListRoomSummary( val inviteSender: InviteSender?, val isTombstoned: Boolean, val heroes: ImmutableList, + val isSpace: Boolean, ) { val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE && (numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0) || diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt index f06e5a1a27..1e763843af 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt @@ -102,6 +102,15 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider = emptyList(), isTombstoned: Boolean = false, + isSpace: Boolean = false, ) = RoomListRoomSummary( id = id, roomId = RoomId(id), @@ -172,4 +182,5 @@ internal fun aRoomListRoomSummary( canonicalAlias = canonicalAlias, heroes = heroes.toImmutableList(), isTombstoned = isTombstoned, + isSpace = isSpace ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt index 55b3f1ffee..4f9b047990 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt @@ -85,6 +85,7 @@ internal fun createRoomListRoomSummary( heroes: List = emptyList(), timestamp: String? = null, isTombstoned: Boolean = false, + isSpace: Boolean = false, ) = RoomListRoomSummary( id = A_ROOM_ID.value, roomId = A_ROOM_ID, @@ -106,4 +107,5 @@ internal fun createRoomListRoomSummary( isDm = false, heroes = heroes.toPersistentList(), isTombstoned = isTombstoned, + isSpace = isSpace ) From b2306258b425e16237fa5ff1148d3894e42481ac Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 14:40:47 +0200 Subject: [PATCH 03/73] Update SDK --- gradle/libs.versions.toml | 2 +- .../libraries/matrix/api/encryption/RecoveryException.kt | 1 + .../matrix/impl/encryption/RecoveryExceptionMapper.kt | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ba09935e55..b58d63d0b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -166,7 +166,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.10.1" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.10.2" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/RecoveryException.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/RecoveryException.kt index 70b335d4f9..7dffbf3653 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/RecoveryException.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/RecoveryException.kt @@ -11,6 +11,7 @@ import io.element.android.libraries.matrix.api.exception.ClientException sealed class RecoveryException(message: String) : Exception(message) { class SecretStorage(message: String) : RecoveryException(message) + class Import(message: String) : RecoveryException(message) data object BackupExistsOnServer : RecoveryException("BackupExistsOnServer") data class Client(val exception: ClientException) : RecoveryException(exception.message ?: "Unknown error") } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt index b9679eb160..5568d008ec 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt @@ -20,6 +20,9 @@ fun Throwable.mapRecoveryException(): RecoveryException { message = errorMessage ) is RustRecoveryException.BackupExistsOnServer -> RecoveryException.BackupExistsOnServer + is RustRecoveryException.Import -> RecoveryException.Import( + message = errorMessage + ) is RustRecoveryException.Client -> RecoveryException.Client( source.mapClientException() ) From 6edb9acc2bc3dcc370abbe8ef6a7dc71cecdac51 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 30 Sep 2025 17:09:45 +0200 Subject: [PATCH 04/73] Let SpaceId be an alias of RoomId --- .../matrix/api/core/MatrixPatterns.kt | 8 -------- .../libraries/matrix/api/core/SpaceId.kt | 18 +----------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/MatrixPatterns.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/MatrixPatterns.kt index 26a030d361..c833d46718 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/MatrixPatterns.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/MatrixPatterns.kt @@ -69,14 +69,6 @@ object MatrixPatterns { str matches PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER } - /** - * Tells if a string is a valid space id. This is an alias for [isRoomId] - * - * @param str the string to test - * @return true if the string is a valid space Id - */ - fun isSpaceId(str: String?) = isRoomId(str) - /** * Tells if a string is a valid room id. * diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/SpaceId.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/SpaceId.kt index 74074ed8e4..6db907bacd 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/SpaceId.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/core/SpaceId.kt @@ -7,23 +7,7 @@ package io.element.android.libraries.matrix.api.core -import io.element.android.libraries.androidutils.metadata.isInDebug -import java.io.Serializable - -@JvmInline -value class SpaceId(val value: String) : Serializable { - init { - if (isInDebug && !MatrixPatterns.isSpaceId(value)) { - error( - "`$value` is not a valid space id.\n" + - "Space ids are the same as room ids.\n" + - "Example space id: `!space_id:domain`." - ) - } - } - - override fun toString(): String = value -} +typealias SpaceId = RoomId /** * Value to use when no space is selected by the user. From ccf34dc6314266c303d3ef7143726a0989a7e8c4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 30 Sep 2025 14:50:13 +0200 Subject: [PATCH 05/73] Enable leave space entry point. --- .../io/element/android/features/space/impl/root/SpaceView.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index 870e294ba5..da21a166b1 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -202,7 +202,7 @@ private fun LoadingMoreIndicator( private fun SpaceViewTopBar( currentSpace: SpaceRoom?, onBackClick: () -> Unit, - @Suppress("unused") onLeaveSpaceClick: () -> Unit, + onLeaveSpaceClick: () -> Unit, onShareSpace: () -> Unit, modifier: Modifier = Modifier, ) { @@ -247,8 +247,6 @@ private fun SpaceViewTopBar( ) } ) - /* - // TODO re-enable when we have SDK APIs to leave a space DropdownMenuItem( onClick = { showMenu = false @@ -263,7 +261,6 @@ private fun SpaceViewTopBar( ) } ) - */ } }, ) From c83fda1cadae3c13dc14a61d97ed940009deec20 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 30 Sep 2025 15:32:59 +0200 Subject: [PATCH 06/73] Leave space: Fix UI issue on top bar. --- .../features/space/impl/leave/LeaveSpaceView.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt index 2a3cd73ea9..6952229f3a 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt @@ -71,6 +71,12 @@ fun LeaveSpaceView( ) { Scaffold( modifier = modifier, + topBar = { + LeaveSpaceHeader( + state = state, + onBackClick = onCancel, + ) + }, containerColor = ElementTheme.colors.bgCanvasDefault, ) { padding -> Column( @@ -81,10 +87,6 @@ fun LeaveSpaceView( .fillMaxSize() .padding(16.dp) ) { - LeaveSpaceHeader( - state = state, - onBackClick = onCancel, - ) LazyColumn( modifier = Modifier .weight(1f), From c459af6e61d94519f58b27f5c70d94793a987583 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 30 Sep 2025 15:27:55 +0200 Subject: [PATCH 07/73] Leave space: use the SDK API. --- .../space/impl/leave/LeaveSpaceNode.kt | 20 +- .../space/impl/leave/LeaveSpacePresenter.kt | 76 +++++--- .../space/impl/leave/LeaveSpaceState.kt | 8 +- .../impl/leave/LeaveSpaceStateProvider.kt | 5 + .../space/impl/leave/LeaveSpaceView.kt | 128 +++++++------ .../features/space/impl/root/SpaceView.kt | 9 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../impl/leave/LeaveSpacePresenterTest.kt | 179 ++++++++++++++++-- .../space/impl/leave/LeaveSpaceStateTest.kt | 23 +++ .../matrix/api/spaces/LeaveSpaceHandle.kt | 34 ++++ .../matrix/api/spaces/LeaveSpaceRoom.kt | 13 ++ .../matrix/api/spaces/SpaceService.kt | 2 + .../impl/spaces/RustLeaveSpaceHandle.kt | 59 ++++++ .../matrix/impl/spaces/RustSpaceService.kt | 11 ++ .../test/spaces/FakeLeaveSpaceHandle.kt | 34 ++++ .../matrix/test/spaces/FakeSpaceService.kt | 6 + 16 files changed, 493 insertions(+), 118 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceHandle.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceRoom.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeLeaveSpaceHandle.kt diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceNode.kt index df313481a1..c60bddea1d 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceNode.kt @@ -9,21 +9,39 @@ package io.element.android.features.space.impl.leave import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.features.space.impl.di.SpaceFlowScope +import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.matrix.api.MatrixClient @ContributesNode(SpaceFlowScope::class) @AssistedInject class LeaveSpaceNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val presenter: LeaveSpacePresenter, + matrixClient: MatrixClient, + presenterFactory: LeaveSpacePresenter.Factory, ) : Node(buildContext, plugins = plugins) { + private val inputs: SpaceEntryPoint.Inputs = inputs() + private val leaveSpaceHandle = matrixClient.spaceService.getLeaveSpaceHandle(inputs.roomId) + private val presenter: LeaveSpacePresenter = presenterFactory.create(leaveSpaceHandle) + + override fun onBuilt() { + super.onBuilt() + lifecycle.subscribe( + onDestroy = { + leaveSpaceHandle.close() + } + ) + } + @Composable override fun View(modifier: Modifier) { val state = presenter.present() diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt index 7af18c1b6d..2754364676 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt @@ -9,65 +9,79 @@ package io.element.android.features.space.impl.leave import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import dev.zacsweers.metro.Inject +import androidx.compose.runtime.setValue +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory +import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.architecture.map import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.spaces.SpaceRoom -import io.element.android.libraries.matrix.api.spaces.SpaceRoomList -import kotlinx.collections.immutable.ImmutableList +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentSetOf -import kotlinx.collections.immutable.toPersistentList +import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentSet import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import kotlin.jvm.optionals.getOrNull -@Inject +@AssistedInject class LeaveSpacePresenter( - private val spaceRoomList: SpaceRoomList, + @Assisted private val leaveSpaceHandle: LeaveSpaceHandle, ) : Presenter { + @AssistedFactory + fun interface Factory { + fun create(leaveSpaceHandle: LeaveSpaceHandle): LeaveSpacePresenter + } + @Composable override fun present(): LeaveSpaceState { val coroutineScope = rememberCoroutineScope() - val currentSpace by spaceRoomList.currentSpaceFlow.collectAsState() + var currentSpace: LeaveSpaceRoom? by remember { mutableStateOf(null) } val leaveSpaceAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val selectedRoomIds = remember { mutableStateOf>(persistentSetOf()) } - val joinedSpaceRooms by produceState(emptyList()) { - // TODO Get the joined room from the SDK, should also have the isLastAdmin boolean - val rooms = emptyList() - // By default select all rooms - selectedRoomIds.value = rooms.map { it.roomId }.toPersistentSet() - value = rooms + val leaveSpaceRooms by produceState(AsyncData.Loading()) { + val rooms = leaveSpaceHandle.rooms() + val (currentRoom, otherRooms) = rooms.getOrNull() + .orEmpty() + .partition { it.spaceRoom.roomId == leaveSpaceHandle.id } + currentSpace = currentRoom.firstOrNull() + // By default select all rooms that can be left + selectedRoomIds.value = otherRooms + .filter { it.isLastAdmin.not() } + .map { it.spaceRoom.roomId } + .toPersistentSet() + value = rooms.fold( + onSuccess = { AsyncData.Success(otherRooms) }, + onFailure = { AsyncData.Failure(it) } + ) } - val selectableSpaceRooms by produceState>>( - initialValue = AsyncData.Uninitialized, - key1 = joinedSpaceRooms, + val selectableSpaceRooms by produceState( + initialValue = AsyncData.Loading(), + key1 = leaveSpaceRooms, key2 = selectedRoomIds.value, ) { - value = AsyncData.Success( - joinedSpaceRooms.map { + value = leaveSpaceRooms.map { list -> + list.orEmpty().map { room -> SelectableSpaceRoom( - spaceRoom = it, - // TODO Get this value from the SDK - isLastAdmin = false, - isSelected = selectedRoomIds.value.contains(it.roomId), + spaceRoom = room.spaceRoom, + isLastAdmin = room.isLastAdmin, + isSelected = selectedRoomIds.value.contains(room.spaceRoom.roomId), ) - }.toPersistentList() - ) + }.toImmutableList() + } } fun handleEvents(event: LeaveSpaceEvents) { @@ -102,7 +116,8 @@ class LeaveSpacePresenter( } return LeaveSpaceState( - spaceName = currentSpace.getOrNull()?.name, + spaceName = currentSpace?.spaceRoom?.name, + isLastAdmin = currentSpace?.isLastAdmin == true, selectableSpaceRooms = selectableSpaceRooms, leaveSpaceAction = leaveSpaceAction.value, eventSink = ::handleEvents, @@ -111,11 +126,10 @@ class LeaveSpacePresenter( private fun CoroutineScope.leaveSpace( leaveSpaceAction: MutableState>, - @Suppress("unused") selectedRoomIds: Set, + selectedRoomIds: Set, ) = launch { runUpdatingState(leaveSpaceAction) { - // TODO SDK API call to leave all the rooms and space - Result.failure(Exception("Not implemented")) + leaveSpaceHandle.leave(selectedRoomIds.toList()) } } } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceState.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceState.kt index f63eef2333..0f2a0f93f6 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceState.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceState.kt @@ -13,6 +13,7 @@ import kotlinx.collections.immutable.ImmutableList data class LeaveSpaceState( val spaceName: String?, + val isLastAdmin: Boolean, val selectableSpaceRooms: AsyncData>, val leaveSpaceAction: AsyncAction, val eventSink: (LeaveSpaceEvents) -> Unit, @@ -25,7 +26,12 @@ data class LeaveSpaceState( /** * True if we should show the quick action to select/deselect all rooms. */ - val showQuickAction = selectableRooms.isNotEmpty() + val showQuickAction = isLastAdmin.not() && selectableRooms.isNotEmpty() + + /** + * True if we should show the leave button. + */ + val showLeaveButton = isLastAdmin.not() && selectableSpaceRooms is AsyncData.Success /** * True if there all the selectable rooms are selected. diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt index 6795cba3a7..16eb85442c 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt @@ -105,15 +105,20 @@ class LeaveSpaceStateProvider : PreviewParameterProvider { aLeaveSpaceState( selectableSpaceRooms = AsyncData.Failure(Exception("An error")), ), + aLeaveSpaceState( + isLastAdmin = true, + ), ) } fun aLeaveSpaceState( spaceName: String? = "Space name", + isLastAdmin: Boolean = false, selectableSpaceRooms: AsyncData> = AsyncData.Uninitialized, leaveSpaceAction: AsyncAction = AsyncAction.Uninitialized, ) = LeaveSpaceState( spaceName = spaceName, + isLastAdmin = isLastAdmin, selectableSpaceRooms = selectableSpaceRooms, leaveSpaceAction = leaveSpaceAction, eventSink = { } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt index 6952229f3a..c28b1661c7 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt @@ -9,8 +9,10 @@ package io.element.android.features.space.impl.leave +import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize @@ -85,41 +87,42 @@ fun LeaveSpaceView( .imePadding() .consumeWindowInsets(padding) .fillMaxSize() - .padding(16.dp) ) { LazyColumn( modifier = Modifier .weight(1f), ) { - when (state.selectableSpaceRooms) { - is AsyncData.Success -> { - // List rooms where the user is the only admin - state.selectableSpaceRooms.data.forEach { selectableSpaceRoom -> - item { - SpaceItem( - selectableSpaceRoom = selectableSpaceRoom, - showCheckBox = state.hasOnlyLastAdminRoom.not(), - onClick = { - state.eventSink(LeaveSpaceEvents.ToggleRoomSelection(selectableSpaceRoom.spaceRoom.roomId)) - } - ) + if (state.isLastAdmin.not()) { + when (state.selectableSpaceRooms) { + is AsyncData.Success -> { + // List rooms where the user is the only admin + state.selectableSpaceRooms.data.forEach { selectableSpaceRoom -> + item { + SpaceItem( + selectableSpaceRoom = selectableSpaceRoom, + showCheckBox = state.hasOnlyLastAdminRoom.not(), + onClick = { + state.eventSink(LeaveSpaceEvents.ToggleRoomSelection(selectableSpaceRoom.spaceRoom.roomId)) + } + ) + } } } - } - is AsyncData.Failure -> item { - AsyncFailure( - throwable = state.selectableSpaceRooms.error, - onRetry = null, - ) - } - is AsyncData.Loading, - AsyncData.Uninitialized -> item { - AsyncLoading() + is AsyncData.Failure -> item { + AsyncFailure( + throwable = state.selectableSpaceRooms.error, + onRetry = null, + ) + } + is AsyncData.Loading, + AsyncData.Uninitialized -> item { + AsyncLoading() + } } } } LeaveSpaceButtons( - showLeaveButton = state.selectableSpaceRooms is AsyncData.Success, + showLeaveButton = state.showLeaveButton, selectedRoomsCount = state.selectedRoomsCount, onLeaveSpace = { state.eventSink(LeaveSpaceEvents.LeaveSpace) @@ -132,6 +135,7 @@ fun LeaveSpaceView( AsyncActionView( async = state.leaveSpaceAction, onSuccess = { /* Nothing to do, the screen will be dismissed automatically */ }, + errorMessage = { stringResource(CommonStrings.error_unknown) }, onErrorDismiss = { state.eventSink(LeaveSpaceEvents.CloseError) }, ) } @@ -152,11 +156,13 @@ private fun LeaveSpaceHeader( modifier = Modifier.padding(top = 0.dp, bottom = 8.dp, start = 24.dp, end = 24.dp), iconStyle = BigIcon.Style.AlertSolid, title = stringResource( - R.string.screen_leave_space_title, + if (state.isLastAdmin) R.string.screen_leave_space_title_last_admin else R.string.screen_leave_space_title, state.spaceName ?: stringResource(CommonStrings.common_space) ), subTitle = - if (state.selectableSpaceRooms is AsyncData.Success && state.selectableSpaceRooms.data.isNotEmpty()) { + if (state.isLastAdmin) { + stringResource(R.string.screen_leave_space_subtitle_last_admin) + } else if (state.selectableSpaceRooms is AsyncData.Success && state.selectableSpaceRooms.data.isNotEmpty()) { if (state.hasOnlyLastAdminRoom) { stringResource(R.string.screen_leave_space_subtitle_only_last_admin) } else { @@ -168,34 +174,35 @@ private fun LeaveSpaceHeader( ) if (state.showQuickAction) { if (state.areAllSelected) { - Text( - modifier = Modifier - .align(Alignment.End) - .clickable { - state.eventSink(LeaveSpaceEvents.DeselectAllRooms) - } - .padding(vertical = 8.dp, horizontal = 8.dp), - text = stringResource(CommonStrings.common_deselect_all), - color = ElementTheme.colors.textActionPrimary, - style = ElementTheme.typography.fontBodyMdMedium, - ) + QuickActionButton(CommonStrings.common_deselect_all) { + state.eventSink(LeaveSpaceEvents.DeselectAllRooms) + } } else { - Text( - modifier = Modifier - .align(Alignment.End) - .clickable { - state.eventSink(LeaveSpaceEvents.SelectAllRooms) - } - .padding(vertical = 8.dp, horizontal = 8.dp), - text = stringResource(CommonStrings.common_select_all), - color = ElementTheme.colors.textActionPrimary, - style = ElementTheme.typography.fontBodyMdMedium, - ) + QuickActionButton(resId = CommonStrings.common_select_all) { + state.eventSink(LeaveSpaceEvents.SelectAllRooms) + } } } } } +@Composable +private fun ColumnScope.QuickActionButton( + @StringRes resId: Int, + onClick: () -> Unit, +) { + Text( + modifier = Modifier + .align(Alignment.End) + .padding(end = 8.dp) + .clickable(onClick = onClick) + .padding(8.dp), + text = stringResource(resId), + color = ElementTheme.colors.textActionPrimary, + style = ElementTheme.typography.fontBodyMdMedium, + ) +} + @Composable private fun LeaveSpaceButtons( showLeaveButton: Boolean, @@ -204,7 +211,7 @@ private fun LeaveSpaceButtons( onCancel: () -> Unit, ) { ButtonColumnMolecule( - modifier = Modifier.padding(top = 16.dp) + modifier = Modifier.padding(16.dp) ) { if (showLeaveButton) { val text = if (selectedRoomsCount > 0) { @@ -220,6 +227,8 @@ private fun LeaveSpaceButtons( destructive = true, ) } + // TODO For least admin space, add a button to open the settings. + // See https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=4622-59600 TextButton( modifier = Modifier.fillMaxWidth(), text = stringResource(CommonStrings.action_cancel), @@ -302,18 +311,15 @@ private fun SpaceItem( ) } // Number of members - val subTitle = buildString { - append( - pluralStringResource( - CommonPlurals.common_member_count, - room.numJoinedMembers, - room.numJoinedMembers - ) - ) - if (selectableSpaceRoom.isLastAdmin) { - append(" ") - append(stringResource(R.string.screen_leave_space_last_admin_info)) - } + val membersCount = pluralStringResource( + CommonPlurals.common_member_count, + room.numJoinedMembers, + room.numJoinedMembers + ) + val subTitle = if (selectableSpaceRoom.isLastAdmin) { + stringResource(R.string.screen_leave_space_last_admin_info, membersCount) + } else { + membersCount } Text( modifier = Modifier.padding(end = 16.dp), diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index da21a166b1..25d4e69b9c 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -252,11 +252,16 @@ private fun SpaceViewTopBar( showMenu = false onLeaveSpaceClick() }, - text = { Text(stringResource(id = CommonStrings.action_leave)) }, + text = { + Text( + text = stringResource(id = CommonStrings.action_leave), + color = ElementTheme.colors.textCriticalPrimary, + ) + }, leadingIcon = { Icon( imageVector = CompoundIcons.Leave(), - tint = ElementTheme.colors.iconSecondary, + tint = ElementTheme.colors.iconCriticalPrimary, contentDescription = null, ) } diff --git a/features/space/impl/src/main/res/values/localazy.xml b/features/space/impl/src/main/res/values/localazy.xml index 07c5468ce6..c6ced29d41 100644 --- a/features/space/impl/src/main/res/values/localazy.xml +++ b/features/space/impl/src/main/res/values/localazy.xml @@ -1,11 +1,13 @@ - "(Admin)" + "%1$s (Admin)" "Leave %1$d room and space" "Leave %1$d rooms and space" "Select the rooms you’d like to leave which you\'re not the only administrator for:" + "You need to assign another admin for this space before you can leave." "You will not be removed from the following room(s) because you\'re the only administrator:" "Leave %1$s?" + "You are the only admin for %1$s" diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt index ee8962a345..b5d6f90923 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt @@ -5,60 +5,197 @@ * Please see LICENSE files in the repository root for full details. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - package io.element.android.features.space.impl.leave import com.google.common.truth.Truth.assertThat import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.matrix.api.spaces.SpaceRoomList +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_ROOM_ID_2 +import io.element.android.libraries.matrix.test.A_SPACE_ID import io.element.android.libraries.matrix.test.A_SPACE_NAME -import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList +import io.element.android.libraries.matrix.test.spaces.FakeLeaveSpaceHandle import io.element.android.libraries.previewutils.room.aSpaceRoom +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Test class LeaveSpacePresenterTest { + private val aSpace = aSpaceRoom( + roomId = A_SPACE_ID, + name = A_SPACE_NAME, + ) + @Test fun `present - initial state`() = runTest { - val presenter = createLeaveSpacePresenter() + val presenter = createLeaveSpacePresenter( + leaveSpaceHandle = FakeLeaveSpaceHandle( + roomsResult = { Result.success(emptyList()) }, + ), + ) presenter.test { val state = awaitItem() assertThat(state.spaceName).isNull() - assertThat(state.selectableSpaceRooms).isEqualTo(AsyncData.Uninitialized) + assertThat(state.isLastAdmin).isFalse() + assertThat(state.selectableSpaceRooms.isLoading()).isTrue() assertThat(state.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) - skipItems(1) + cancelAndIgnoreRemainingEvents() } } @Test - fun `present - current space name`() = runTest { - val fakeSpaceRoomList = FakeSpaceRoomList() + fun `present - fail to load rooms`() = runTest { val presenter = createLeaveSpacePresenter( - spaceRoomList = fakeSpaceRoomList, + leaveSpaceHandle = FakeLeaveSpaceHandle( + roomsResult = { Result.failure(AN_EXCEPTION) }, + ) ) presenter.test { val state = awaitItem() - advanceUntilIdle() - assertThat(state.spaceName).isNull() - val aSpace = aSpaceRoom( - name = A_SPACE_NAME + assertThat(state.selectableSpaceRooms.isLoading()).isTrue() + assertThat(state.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) + skipItems(2) + val stateError = awaitItem() + assertThat(stateError.selectableSpaceRooms.isFailure()).isTrue() + } + } + + @Test + fun `present - current space name and is last admin`() = runTest { + val presenter = createLeaveSpacePresenter( + leaveSpaceHandle = FakeLeaveSpaceHandle( + roomsResult = { Result.success(listOf(aLeaveSpaceRoom(spaceRoom = aSpace, isLastAdmin = true))) }, ) - fakeSpaceRoomList.emitCurrentSpace(aSpace) + ) + presenter.test { + val state = awaitItem() + assertThat(state.spaceName).isNull() + skipItems(3) + val finalState = awaitItem() + assertThat(finalState.spaceName).isEqualTo(A_SPACE_NAME) + assertThat(finalState.isLastAdmin).isTrue() + // The current state is not in the sub room list + assertThat(finalState.selectableSpaceRooms.dataOrNull()!!).isEmpty() + } + } + + @Test + fun `present - leave space and sub rooms`() = runTest { + val leaveResult = lambdaRecorder, Result> { Result.success(Unit) } + val presenter = createLeaveSpacePresenter( + leaveSpaceHandle = FakeLeaveSpaceHandle( + roomsResult = { + Result.success( + listOf( + LeaveSpaceRoom(aSpaceRoom(roomId = A_ROOM_ID), isLastAdmin = false), + LeaveSpaceRoom(aSpaceRoom(roomId = A_ROOM_ID_2), isLastAdmin = true), + ) + ) + }, + leaveResult = leaveResult, + ) + ) + presenter.test { + skipItems(4) + val state = awaitItem() + assertThat(state.spaceName).isNull() + assertThat(state.isLastAdmin).isFalse() + val data = state.selectableSpaceRooms.dataOrNull()!! + assertThat(data.size).isEqualTo(2) + // Only one room is selectable as the user is the last admin in the other one + val room1 = data[0] + assertThat(room1.spaceRoom.roomId).isEqualTo(A_ROOM_ID) + assertThat(room1.isSelected).isTrue() + assertThat(room1.isLastAdmin).isFalse() + val room2 = data[1] + assertThat(room2.spaceRoom.roomId).isEqualTo(A_ROOM_ID_2) + assertThat(room2.isSelected).isFalse() + assertThat(room2.isLastAdmin).isTrue() + // Deselect all + state.eventSink(LeaveSpaceEvents.DeselectAllRooms) skipItems(1) - assertThat(awaitItem().spaceName).isEqualTo(A_SPACE_NAME) + val stateAllDeselected = awaitItem() + val dataAllDeselected = stateAllDeselected.selectableSpaceRooms.dataOrNull()!! + assertThat(dataAllDeselected.any { it.isSelected }).isFalse() + // Select all + stateAllDeselected.eventSink(LeaveSpaceEvents.SelectAllRooms) + skipItems(1) + val stateAllSelected = awaitItem() + val dataAllSelected = stateAllSelected.selectableSpaceRooms.dataOrNull()!! + // The last admin room should not be selected + assertThat(dataAllSelected.count { it.isSelected }).isEqualTo(1) + // Toggle selection of the first room + stateAllSelected.eventSink(LeaveSpaceEvents.ToggleRoomSelection(A_ROOM_ID)) + skipItems(1) + val stateOneDeselected = awaitItem() + val dataOneDeselected = stateOneDeselected.selectableSpaceRooms.dataOrNull()!! + assertThat(dataOneDeselected[0].isSelected).isFalse() + // Toggle selection of the first room + stateOneDeselected.eventSink(LeaveSpaceEvents.ToggleRoomSelection(A_ROOM_ID)) + skipItems(1) + val stateOneSelected = awaitItem() + val dataOneSelected = stateOneSelected.selectableSpaceRooms.dataOrNull()!! + assertThat(dataOneSelected[0].isSelected).isTrue() + // Leave space + stateOneSelected.eventSink(LeaveSpaceEvents.LeaveSpace) + val stateLeaving = awaitItem() + assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading) + val stateLeft = awaitItem() + assertThat(stateLeft.leaveSpaceAction.isSuccess()).isTrue() + leaveResult.assertions().isCalledOnce().with( + value(listOf(A_ROOM_ID)) + ) + } + } + + @Test + fun `present - leave space error and close`() = runTest { + val leaveResult = lambdaRecorder, Result> { + Result.failure(AN_EXCEPTION) + } + val presenter = createLeaveSpacePresenter( + leaveSpaceHandle = FakeLeaveSpaceHandle( + roomsResult = { Result.success(emptyList()) }, + leaveResult = leaveResult, + ) + ) + presenter.test { + skipItems(3) + val state = awaitItem() + state.eventSink(LeaveSpaceEvents.LeaveSpace) + val stateLeaving = awaitItem() + assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading) + val stateError = awaitItem() + assertThat(stateError.leaveSpaceAction.isFailure()).isTrue() + // Close error + stateError.eventSink(LeaveSpaceEvents.CloseError) + val stateErrorClosed = awaitItem() + assertThat(stateErrorClosed.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) } } private fun createLeaveSpacePresenter( - spaceRoomList: SpaceRoomList = FakeSpaceRoomList(), + leaveSpaceHandle: LeaveSpaceHandle = FakeLeaveSpaceHandle(), ): LeaveSpacePresenter { return LeaveSpacePresenter( - spaceRoomList = spaceRoomList, + leaveSpaceHandle = leaveSpaceHandle, ) } } + +private fun aLeaveSpaceRoom( + spaceRoom: SpaceRoom = aSpaceRoom( + roomId = A_SPACE_ID, + name = A_SPACE_NAME, + ), + isLastAdmin: Boolean = false, +) = LeaveSpaceRoom( + spaceRoom = spaceRoom, + isLastAdmin = isLastAdmin, +) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateTest.kt index eaf3f1a783..bfec2f2326 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateTest.kt @@ -20,6 +20,7 @@ class LeaveSpaceStateTest { selectableSpaceRooms = AsyncData.Loading() ) assertThat(sut.showQuickAction).isFalse() + assertThat(sut.showLeaveButton).isFalse() assertThat(sut.areAllSelected).isTrue() assertThat(sut.hasOnlyLastAdminRoom).isFalse() assertThat(sut.selectedRoomsCount).isEqualTo(0) @@ -33,11 +34,29 @@ class LeaveSpaceStateTest { ) ) assertThat(sut.showQuickAction).isFalse() + assertThat(sut.showLeaveButton).isTrue() assertThat(sut.areAllSelected).isTrue() assertThat(sut.hasOnlyLastAdminRoom).isFalse() assertThat(sut.selectedRoomsCount).isEqualTo(0) } + @Test + fun `test last admin`() { + val sut = aLeaveSpaceState( + isLastAdmin = true, + selectableSpaceRooms = AsyncData.Success( + persistentListOf( + aSelectableSpaceRoom(isLastAdmin = false, isSelected = false), + ) + ) + ) + assertThat(sut.showQuickAction).isFalse() + assertThat(sut.showLeaveButton).isFalse() + assertThat(sut.areAllSelected).isFalse() + assertThat(sut.hasOnlyLastAdminRoom).isFalse() + assertThat(sut.selectedRoomsCount).isEqualTo(0) + } + @Test fun `test no last admin, 1 selected, 1 not selected`() { val sut = aLeaveSpaceState( @@ -49,6 +68,7 @@ class LeaveSpaceStateTest { ) ) assertThat(sut.showQuickAction).isTrue() + assertThat(sut.showLeaveButton).isTrue() assertThat(sut.areAllSelected).isFalse() assertThat(sut.hasOnlyLastAdminRoom).isFalse() assertThat(sut.selectedRoomsCount).isEqualTo(1) @@ -65,6 +85,7 @@ class LeaveSpaceStateTest { ) ) assertThat(sut.showQuickAction).isTrue() + assertThat(sut.showLeaveButton).isTrue() assertThat(sut.areAllSelected).isTrue() assertThat(sut.hasOnlyLastAdminRoom).isFalse() assertThat(sut.selectedRoomsCount).isEqualTo(2) @@ -82,6 +103,7 @@ class LeaveSpaceStateTest { ) ) assertThat(sut.showQuickAction).isTrue() + assertThat(sut.showLeaveButton).isTrue() assertThat(sut.areAllSelected).isTrue() assertThat(sut.hasOnlyLastAdminRoom).isFalse() assertThat(sut.selectedRoomsCount).isEqualTo(2) @@ -98,6 +120,7 @@ class LeaveSpaceStateTest { ) ) assertThat(sut.showQuickAction).isFalse() + assertThat(sut.showLeaveButton).isTrue() assertThat(sut.areAllSelected).isTrue() assertThat(sut.hasOnlyLastAdminRoom).isTrue() assertThat(sut.selectedRoomsCount).isEqualTo(0) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceHandle.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceHandle.kt new file mode 100644 index 0000000000..292a973dda --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceHandle.kt @@ -0,0 +1,34 @@ +/* + * 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.libraries.matrix.api.spaces + +import io.element.android.libraries.matrix.api.core.RoomId + +interface LeaveSpaceHandle { + /** + * The id of the space to leave. + */ + val id: RoomId + + /** + * Get a list of rooms that can be left when leaving the space. + * It will include the current space and all the subspaces and rooms that the user has joined. + */ + suspend fun rooms(): Result> + + /** + * Leave the space and the given rooms. + * If [roomIds] is empty, only the space will be left. + */ + suspend fun leave(roomIds: List): Result + + /** + * Close the handle and free resources. + */ + fun close() +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceRoom.kt new file mode 100644 index 0000000000..fb90896e05 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/LeaveSpaceRoom.kt @@ -0,0 +1,13 @@ +/* + * 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.libraries.matrix.api.spaces + +data class LeaveSpaceRoom( + val spaceRoom: SpaceRoom, + val isLastAdmin: Boolean, +) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt index b4572ad0bb..f1fea6b62a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt @@ -15,4 +15,6 @@ interface SpaceService { suspend fun joinedSpaces(): Result> fun spaceRoomList(id: RoomId): SpaceRoomList + + fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt new file mode 100644 index 0000000000..aa8cff7024 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt @@ -0,0 +1,59 @@ +/* + * 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.libraries.matrix.impl.spaces + +import io.element.android.libraries.core.extensions.runCatchingExceptions +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import timber.log.Timber +import org.matrix.rustcomponents.sdk.LeaveSpaceHandle as RustLeaveSpaceHandle + +class RustLeaveSpaceHandle( + override val id: RoomId, + private val spaceRoomMapper: SpaceRoomMapper, + sessionCoroutineScope: CoroutineScope, + private val innerProvider: suspend () -> RustLeaveSpaceHandle, +) : LeaveSpaceHandle { + private val inner = CompletableDeferred() + + init { + sessionCoroutineScope.launch { + inner.complete(innerProvider()) + } + } + + override suspend fun rooms(): Result> = runCatchingExceptions { + inner.await().rooms().map { leaveSpaceRoom -> + LeaveSpaceRoom( + spaceRoom = spaceRoomMapper.map(leaveSpaceRoom.spaceRoom), + isLastAdmin = leaveSpaceRoom.isLastAdmin, + ) + } + } + + override suspend fun leave(roomIds: List): Result = runCatchingExceptions { + // Ensure the space is included and is the last room to be left + val roomToLeave = roomIds - id + id + inner.await().leave(roomToLeave.map { it.value }) + } + + @OptIn(ExperimentalCoroutinesApi::class) + override fun close() { + Timber.d("Destroying LeaveSpaceHandle $id") + try { + inner.getCompleted().destroy() + } catch (_: Exception) { + // Ignore, we just want to make sure it's completed + } + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt index 86d50a477c..784cc586e2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.spaces import io.element.android.libraries.core.coroutine.childScope import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.api.spaces.SpaceService @@ -64,6 +65,16 @@ class RustSpaceService( ) } + override fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle { + return RustLeaveSpaceHandle( + id = spaceId, + spaceRoomMapper = spaceRoomMapper, + sessionCoroutineScope = sessionCoroutineScope, + ) { + innerSpaceService.leaveSpace(spaceId.value) + } + } + init { innerSpaceService .spaceListUpdate() diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeLeaveSpaceHandle.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeLeaveSpaceHandle.kt new file mode 100644 index 0000000000..b19d3f1344 --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeLeaveSpaceHandle.kt @@ -0,0 +1,34 @@ +/* + * 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.libraries.matrix.test.spaces + +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom +import io.element.android.libraries.matrix.test.A_SPACE_ID +import io.element.android.tests.testutils.lambda.lambdaError +import io.element.android.tests.testutils.simulateLongTask + +class FakeLeaveSpaceHandle( + override val id: RoomId = A_SPACE_ID, + private val roomsResult: () -> Result> = { lambdaError() }, + private val leaveResult: (List) -> Result = { lambdaError() }, + private val closeResult: () -> Unit = { lambdaError() }, +) : LeaveSpaceHandle { + override suspend fun rooms(): Result> = simulateLongTask { + roomsResult() + } + + override suspend fun leave(roomIds: List): Result = simulateLongTask { + leaveResult(roomIds) + } + + override fun close() { + return closeResult() + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt index 43cc8ae8d2..d768b175d0 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt @@ -8,6 +8,7 @@ package io.element.android.libraries.matrix.test.spaces import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.api.spaces.SpaceService @@ -20,6 +21,7 @@ import kotlinx.coroutines.flow.asSharedFlow class FakeSpaceService( private val joinedSpacesResult: () -> Result> = { lambdaError() }, private val spaceRoomListResult: (RoomId) -> SpaceRoomList = { lambdaError() }, + private val leaveSpaceHandleResult: (RoomId) -> LeaveSpaceHandle = { lambdaError() }, ) : SpaceService { private val _spaceRoomsFlow = MutableSharedFlow>() override val spaceRoomsFlow: SharedFlow> @@ -36,4 +38,8 @@ class FakeSpaceService( override fun spaceRoomList(id: RoomId): SpaceRoomList { return spaceRoomListResult(id) } + + override fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle { + return leaveSpaceHandleResult(spaceId) + } } From f0b341816b4563d4f34c961a1cba0275c03b9928 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 2 Oct 2025 17:38:47 +0200 Subject: [PATCH 08/73] feature(space) : filter space manually so we can show space invites --- .../matrix/api/roomlist/RoomListFilter.kt | 3 +- .../matrix/impl/roomlist/RoomListFactory.kt | 1 - .../matrix/impl/roomlist/RoomListFilter.kt | 44 +++++++++++++------ .../impl/roomlist/RoomListFilterTest.kt | 28 ++++++++---- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt index 8b9b84eb18..405906a185 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt @@ -58,11 +58,12 @@ sealed interface RoomListFilter { data object Invite : RoomListFilter /** - * A filter that matches either Group or People rooms. + * A filter that matches either Group,People rooms or Space. */ sealed interface Category : RoomListFilter { data object Group : Category data object People : Category + data object Space : Category } /** diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt index 15ba644fcf..53b8127ab8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -29,7 +29,6 @@ import org.matrix.rustcomponents.sdk.RoomList as InnerRoomList private val ROOM_LIST_RUST_FILTERS = listOf( RoomListEntriesDynamicFilterKind.NonLeft, - RoomListEntriesDynamicFilterKind.NonSpace, RoomListEntriesDynamicFilterKind.DeduplicateVersions ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt index 1e4a3fad3e..3fc59d7c44 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt @@ -15,41 +15,57 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary val RoomListFilter.predicate get() = when (this) { - is RoomListFilter.All -> { _: RoomSummary -> true } - is RoomListFilter.Any -> { _: RoomSummary -> true } - RoomListFilter.None -> { _: RoomSummary -> false } + is RoomListFilter.All -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) } + is RoomListFilter.Any -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) } + RoomListFilter.None -> { _ -> false } RoomListFilter.Category.Group -> { roomSummary: RoomSummary -> - !roomSummary.info.isDm && !roomSummary.isInvited() + !roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary) } RoomListFilter.Category.People -> { roomSummary: RoomSummary -> - roomSummary.info.isDm && !roomSummary.isInvited() + roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary) } + RoomListFilter.Category.Space -> IsSpacePredicate RoomListFilter.Favorite -> { roomSummary: RoomSummary -> - roomSummary.info.isFavorite && !roomSummary.isInvited() + roomSummary.info.isFavorite && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary) } RoomListFilter.Unread -> { roomSummary: RoomSummary -> - !roomSummary.isInvited() && (roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread) + NonInvitedPredicate(roomSummary) && + NonSpacePredicate(roomSummary) && + (roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread) } is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary -> - roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) - } - RoomListFilter.Invite -> { roomSummary: RoomSummary -> - roomSummary.isInvited() + roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) && + (NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary)) } + RoomListFilter.Invite -> IsInvitedPredicate } fun List.filter(filter: RoomListFilter): List { return when (filter) { is RoomListFilter.All -> { - val predicates = filter.filters.map { it.predicate } + val predicates = if (filter.filters.isNotEmpty()) { + filter.filters.map { it.predicate } + } else { + listOf(filter.predicate) + } filter { roomSummary -> predicates.all { it(roomSummary) } } } is RoomListFilter.Any -> { - val predicates = filter.filters.map { it.predicate } + val predicates = if (filter.filters.isNotEmpty()) { + filter.filters.map { it.predicate } + } else { + listOf(filter.predicate) + } filter { roomSummary -> predicates.any { it(roomSummary) } } } else -> filter(filter.predicate) } } -private fun RoomSummary.isInvited() = info.currentUserMembership == CurrentUserMembership.INVITED +private val IsSpacePredicate = { roomSummary: RoomSummary -> roomSummary.info.isSpace } + +private val NonSpacePredicate = { roomSummary: RoomSummary -> !IsSpacePredicate(roomSummary) } + +private val IsInvitedPredicate = { roomSummary: RoomSummary -> roomSummary.info.currentUserMembership == CurrentUserMembership.INVITED } + +private val NonInvitedPredicate = { roomSummary: RoomSummary -> !IsInvitedPredicate(roomSummary) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt index ff4e5b29e5..932f9ba6be 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt @@ -41,6 +41,14 @@ class RoomListFilterTest { currentUserMembership = CurrentUserMembership.INVITED ) + private val space = aRoomSummary( + isSpace = true + ) + private val invitedSpace = aRoomSummary( + isSpace = true, + currentUserMembership = CurrentUserMembership.INVITED + ) + private val roomSummaries = listOf( regularRoom, dmRoom, @@ -49,13 +57,15 @@ class RoomListFilterTest { unreadNotificationRoom, roomToSearch, roomWithAccent, - invitedRoom + invitedRoom, + space, + invitedSpace, ) @Test fun `Room list filter all empty`() = runTest { val filter = RoomListFilter.all() - assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries) + assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries - space) } @Test @@ -83,6 +93,12 @@ class RoomListFilterTest { ) } + @Test + fun `Room list filter space`() = runTest { + val filter = RoomListFilter.Category.Space + assertThat(roomSummaries.filter(filter)).containsExactly(space, invitedSpace) + } + @Test fun `Room list filter favorite`() = runTest { val filter = RoomListFilter.Favorite @@ -98,7 +114,7 @@ class RoomListFilterTest { @Test fun `Room list filter invites`() = runTest { val filter = RoomListFilter.Invite - assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom) + assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom, invitedSpace) } @Test @@ -136,10 +152,4 @@ class RoomListFilterTest { ) assertThat(roomSummaries.filter(filter)).isEmpty() } - - @Test - fun `Room list filter all with empty list`() = runTest { - val filter = RoomListFilter.all() - assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries) - } } From 99f3209b7fe375ab43a9df22dcde52078a01272c Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 2 Oct 2025 15:40:56 +0000 Subject: [PATCH 09/73] Update screenshots --- .../features.space.impl.leave_LeaveSpaceView_Day_0_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_1_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_2_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_3_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_4_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_5_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_6_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_7_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_8_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_9_en.png | 3 +++ .../features.space.impl.leave_LeaveSpaceView_Night_0_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_1_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_2_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_3_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_4_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_5_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_6_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_7_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_8_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_9_en.png | 3 +++ 20 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_0_en.png index b3abe80b38..ba768c622f 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5219016a0af4e1e4f7703dcef3400bf030444845dc0ef52f084e69963170bf1e -size 13951 +oid sha256:3c569a42e638a49554127d3dc59c1dda5306e50406a6eaf1033345b44e2fe037 +size 13941 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_1_en.png index c7a2988917..b42cde52d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:964aff2fc49b9d71ebec506bc9acc5010071efca01ed95f240a65b2c91f0f3b1 -size 15852 +oid sha256:b43c73a9da70133fdff8c63dd6ed8b130b76fbbc28977fae9a34733b0f64faea +size 15840 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_2_en.png index 8be29a4767..a6ed2b4caa 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2097486621a733b1662c02849ec71423d00f9c97c679996fafc8f20a4ef27ce -size 43844 +oid sha256:02ea4a02c0901c3d31a86272659f251e3b9299f669177b7a46a9007159989519 +size 44313 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_3_en.png index 3b29fd1488..78de62dc26 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:daff7333af912c8a0d7f009ba10d044aaa7cdfea2dfa3ccff2fd97209bf3278e -size 44225 +oid sha256:0a8d851c9393b9a64642d08be96b0c449ce894fdf69d52d0eb664d83c7005520 +size 44211 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_4_en.png index 6ffb98cf91..9580492e5e 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa05867ac79a3bfb9f59bf1dafb02185274b46e9a5fbf27415a0e907780a0493 -size 36393 +oid sha256:78cc2ef488b13f72da4d1d149329930816e1d91541bbe62eb48c78b61564dc18 +size 35868 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_5_en.png index aba8f0ea75..434ea3b936 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e74abc389c25fa9a5d33ade6d0f8a2242aeb5150fe81a26e26e9b561c46bb802 -size 43010 +oid sha256:426847168cf1cf81df60193ba69d1c02cad567f0a72c03f0b2dadb76e92f41c0 +size 42600 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_6_en.png index 3191bb9c6e..ae57be48c5 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5c8bdf8d389cccb4cced29aa854a70860e9b44cbdde2a25ab95ccd5bc5e1674 -size 39222 +oid sha256:479fb84a857b3fcb15a9bba6a6fac3f8e1309a7d5af9c10c1cfe1d16c2eb678f +size 42208 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_7_en.png index 774c1e01c3..e2a34d1b7f 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbf5d7c5320daa0d6b3c6678a6766c7143bc877850257e2c6923b174dfa9b6d4 -size 34565 +oid sha256:ba7631fe1e5d20946256829e8414f5a305e3a2755d79fc0693fd932bfac40f4a +size 40182 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png index 38f435b1b0..5040a8439e 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:298db58a3f80f4194c5710ceeabec0e49b0e80861b931693d58b1a17f4394b4e -size 13873 +oid sha256:792f623cbd264f29724864f2d8db1c8044580fe309241b0a9afd8bea355ba289 +size 13862 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png new file mode 100644 index 0000000000..8d62c122e7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:520698bcbc65cd2ccbc73aff01132a6b5d39c7d349a814e5a26e584cec5f2eeb +size 26083 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_0_en.png index 1c82d3955f..4b003761fc 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b982dc465fd47dbce6f88321f80c5390ecc90f7e8ad59a76dd44b6c2b9b80c8a -size 13923 +oid sha256:1935a53ffe3653f9c094996a7b62359fe70c18ea0b46a7204969f70ce439b5e7 +size 13924 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_1_en.png index 485fa05bb5..855181d5fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00b13582a4a8a380cc502ca2bb181c1ee7c9f2e1685e1d2a75817107d5ebea99 -size 15393 +oid sha256:f90882b794619797d17c9bdb8ff2e56664a5bd95ab9bee0bb59371f954c0e7ca +size 15395 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_2_en.png index a52fe36b2e..8f6d72cc9e 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ad6ae058adb3decb4733c74ad40e4efdd33744eea3e9a793e92fc6b4cbc1464 -size 42784 +oid sha256:4071cfff533916af1c99636ce6f61e2fbfd8d945dbba1b11e449ce55fd4bd7b9 +size 43148 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_3_en.png index 225298ea51..e4a21c1d3e 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad30950d847bd769e19ce67d8944c16145e929c52210cd54b1ebc5966efe89b5 -size 43221 +oid sha256:03dd230a42399b5db39a57dbde170955c7f40793fced9420e2fcf8c55820b8c4 +size 42948 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_4_en.png index d7a024d955..cd30a49899 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6465f03be41ae02635cbdc94f521059bdd6476c5b2ccfca6f28ccd8898112cea -size 35530 +oid sha256:f8d4a0d5f17cf6781d34af68ec0fae1c64cdf88d59ddf4306db411c4c67fcfd8 +size 34945 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_5_en.png index 171d67f826..6038b2a50e 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af017745220027708f5a84ca639c9990fe7e474a38aaeecc3cba82011d195360 -size 42080 +oid sha256:26fcf6cfae843737df553b143d9cbb8049001548b0c3479e1e24a28e0c5e6527 +size 41632 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_6_en.png index ea980ce184..64dab99eb8 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73f85bf9ec6c6682e293db2c740d206f6d895d79b3f3d30b967ad55aedbb268c -size 37895 +oid sha256:bc8a9e1d6fd7a81cf1ef718d2f3e38babcf96e58e00c2c92827cba0aadd8903e +size 40613 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_7_en.png index 55995f7fd6..5629c9bab1 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49e2727c42d334c539ee14aab396cadd68b1290e6a256ec2f677f7e4801b30e9 -size 32677 +oid sha256:1f0ce9d4bbe5a8bdadee5663e8ad8b9b189aa25b5eec7e7c1a40430c09f7d1d3 +size 38108 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png index a3e293c5f5..76f1c87fd1 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ef494178398bc0f8e7721b7dfde669da4d723aeafa0d4ca6975a58215193416 -size 13848 +oid sha256:fffb92c5520c5b8665ce4be8eba4f1d9133047140ef116562440a40f319dc2ac +size 13852 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png new file mode 100644 index 0000000000..dc1018d69b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ac66ddfcf3125726d2a9a7a83ef23880339f56c12bf2cad68bc969a4deb0f38 +size 25776 From 080280aa5f9f3125c8da2888d4b083992b8d4d5f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 2 Oct 2025 15:59:35 +0000 Subject: [PATCH 10/73] Update screenshots --- ...features.home.impl.components_RoomSummaryRow_Day_32_en.png | 4 ++-- ...features.home.impl.components_RoomSummaryRow_Day_33_en.png | 4 ++-- ...features.home.impl.components_RoomSummaryRow_Day_34_en.png | 4 ++-- ...features.home.impl.components_RoomSummaryRow_Day_35_en.png | 3 +++ ...atures.home.impl.components_RoomSummaryRow_Night_32_en.png | 4 ++-- ...atures.home.impl.components_RoomSummaryRow_Night_33_en.png | 4 ++-- ...atures.home.impl.components_RoomSummaryRow_Night_34_en.png | 4 ++-- ...atures.home.impl.components_RoomSummaryRow_Night_35_en.png | 3 +++ 8 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_35_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_35_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_32_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_32_en.png index 172695b6b2..89cf315b42 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_32_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_32_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ad2d62e2ce270b8548ddf611c3b192e756be0896627ccad28fff84c4ce5e2a1 -size 11938 +oid sha256:98d4e9152dee861cc7afdb3efe57b086c3d9d58d38eeb1345749d31debbf6017 +size 21266 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_33_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_33_en.png index 5430afc3cc..172695b6b2 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_33_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_33_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:541b4210ff0acaf6451a0ce9c6cdc4f120c460086e036fc27e319daa23c7082b -size 17393 +oid sha256:1ad2d62e2ce270b8548ddf611c3b192e756be0896627ccad28fff84c4ce5e2a1 +size 11938 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_34_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_34_en.png index ddd04d3eda..5430afc3cc 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_34_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_34_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:697513adb4fa43d68e8a4477f248e68f64ba305f0ecb6a2e681b8a8b04ceee2b -size 14823 +oid sha256:541b4210ff0acaf6451a0ce9c6cdc4f120c460086e036fc27e319daa23c7082b +size 17393 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_35_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_35_en.png new file mode 100644 index 0000000000..ddd04d3eda --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_35_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:697513adb4fa43d68e8a4477f248e68f64ba305f0ecb6a2e681b8a8b04ceee2b +size 14823 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_32_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_32_en.png index b24babae66..c7a3fd69f5 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_32_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_32_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0c73cab66c885e528bd8723b14cfe28356f0843fd360164c2d6163833a9576b -size 11999 +oid sha256:c24a3b08afe224e9919dd3818c72bd2ff8dd3f38663a6465a10b301ad91e8787 +size 20377 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_33_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_33_en.png index 50455e8053..b24babae66 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_33_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_33_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71e4c4f995456a5502fb057bbb37cebcb9b92af6edf315cff63f92b3541a30a2 -size 17234 +oid sha256:f0c73cab66c885e528bd8723b14cfe28356f0843fd360164c2d6163833a9576b +size 11999 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_34_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_34_en.png index 0ef7d945d7..50455e8053 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_34_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_34_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:466ff5436718dd1871635330108c592ff28727c1628368c11387a9b1f5c73642 -size 14204 +oid sha256:71e4c4f995456a5502fb057bbb37cebcb9b92af6edf315cff63f92b3541a30a2 +size 17234 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_35_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_35_en.png new file mode 100644 index 0000000000..0ef7d945d7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_35_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:466ff5436718dd1871635330108c592ff28727c1628368c11387a9b1f5c73642 +size 14204 From 71f9660295abf06926c0dc59f77d0a5d7da70237 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 2 Oct 2025 19:49:34 +0200 Subject: [PATCH 11/73] Leave space: notify the room membership change --- .../android/libraries/matrix/impl/RustMatrixClient.kt | 5 ++++- .../libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt | 9 +++++++++ .../libraries/matrix/impl/spaces/RustSpaceService.kt | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 3f84621cb7..a84a7bc164 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -147,6 +147,8 @@ class RustMatrixClient( private val innerRoomListService = innerSyncService.roomListService() private val innerSpaceService = innerClient.spaceService() + private val roomMembershipObserver = RoomMembershipObserver() + private val rustSyncService = RustSyncService( inner = innerSyncService, dispatcher = sessionDispatcher, @@ -189,6 +191,7 @@ class RustMatrixClient( override val spaceService: SpaceService = RustSpaceService( innerSpaceService = innerSpaceService, + roomMembershipObserver = roomMembershipObserver, sessionCoroutineScope = sessionCoroutineScope, sessionDispatcher = sessionDispatcher, ) @@ -200,7 +203,7 @@ class RustMatrixClient( ) private val roomInfoMapper = RoomInfoMapper() - private val roomMembershipObserver = RoomMembershipObserver() + private val roomFactory = RustRoomFactory( roomListService = roomListService, innerRoomListService = innerRoomListService, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt index aa8cff7024..e7e629b40b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustLeaveSpaceHandle.kt @@ -9,6 +9,8 @@ package io.element.android.libraries.matrix.impl.spaces import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.CurrentUserMembership +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom import kotlinx.coroutines.CompletableDeferred @@ -21,6 +23,7 @@ import org.matrix.rustcomponents.sdk.LeaveSpaceHandle as RustLeaveSpaceHandle class RustLeaveSpaceHandle( override val id: RoomId, private val spaceRoomMapper: SpaceRoomMapper, + private val roomMembershipObserver: RoomMembershipObserver, sessionCoroutineScope: CoroutineScope, private val innerProvider: suspend () -> RustLeaveSpaceHandle, ) : LeaveSpaceHandle { @@ -45,6 +48,12 @@ class RustLeaveSpaceHandle( // Ensure the space is included and is the last room to be left val roomToLeave = roomIds - id + id inner.await().leave(roomToLeave.map { it.value }) + }.onSuccess { + roomMembershipObserver.notifyUserLeftRoom( + roomId = id, + isSpace = true, + membershipBeforeLeft = CurrentUserMembership.JOINED, + ) } @OptIn(ExperimentalCoroutinesApi::class) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt index 784cc586e2..88f738f0c4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.spaces import io.element.android.libraries.core.coroutine.childScope import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList @@ -38,6 +39,7 @@ class RustSpaceService( private val innerSpaceService: ClientSpaceService, private val sessionCoroutineScope: CoroutineScope, private val sessionDispatcher: CoroutineDispatcher, + private val roomMembershipObserver: RoomMembershipObserver, ) : SpaceService { private val spaceRoomMapper = SpaceRoomMapper() override val spaceRoomsFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) @@ -69,6 +71,7 @@ class RustSpaceService( return RustLeaveSpaceHandle( id = spaceId, spaceRoomMapper = spaceRoomMapper, + roomMembershipObserver = roomMembershipObserver, sessionCoroutineScope = sessionCoroutineScope, ) { innerSpaceService.leaveSpace(spaceId.value) From 9de16fc74f05ea4c83a61031b82cb84d978e24bd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 22:04:31 +0200 Subject: [PATCH 12/73] Format --- .../src/main/kotlin/io/element/android/appnav/RootFlowNode.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 93df005c76..7f5cb13246 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -64,7 +64,9 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import timber.log.Timber -@ContributesNode(AppScope::class) @AssistedInject class RootFlowNode( +@ContributesNode(AppScope::class) +@AssistedInject +class RootFlowNode( @Assisted val buildContext: BuildContext, @Assisted plugins: List, private val sessionStore: SessionStore, From 23ed5e71fdfeb7c02e5dd565aa22abd0e8437bce Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 22:05:38 +0200 Subject: [PATCH 13/73] Add Composable for a Beta label --- .../designsystem/atomic/atoms/BetaLabel.kt | 66 +++++++++++++++++++ .../molecules/IconTitleSubtitleMolecule.kt | 35 ++++++---- 2 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt new file mode 100644 index 0000000000..7ef5b5dec5 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt @@ -0,0 +1,66 @@ +/* + * 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.libraries.designsystem.atomic.atoms + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.internal.DarkColorTokens +import io.element.android.compound.tokens.generated.internal.LightColorTokens +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Text + +@OptIn(CoreColorToken::class) +@Composable +fun BetaLabel( + modifier: Modifier = Modifier, +) { + val (backgroundColor, borderColor, textColor) = if (ElementTheme.isLightTheme) { + listOf( + LightColorTokens.colorGreen300, + LightColorTokens.colorGreen700, + LightColorTokens.colorGreen900, + ) + } else { + listOf( + DarkColorTokens.colorGreen300, + DarkColorTokens.colorGreen700, + DarkColorTokens.colorGreen900, + ) + } + val shape = RoundedCornerShape(size = 6.dp) + Text( + modifier = modifier + .border( + width = 1.dp, + color = borderColor, + shape = shape, + ) + .background( + color = backgroundColor, + shape = shape, + ) + .padding(horizontal = 8.dp, vertical = 4.dp), + text = "BETA", + style = ElementTheme.typography.fontBodySmMedium, + color = textColor, + ) +} + +@PreviewsDayNight +@Composable +internal fun BetaLabelPreview() = ElementPreview { + BetaLabel() +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt index a89a21adbd..be149437f1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt @@ -7,7 +7,9 @@ package io.element.android.libraries.designsystem.atomic.molecules +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -20,6 +22,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.libraries.designsystem.atomic.atoms.BetaLabel import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -32,6 +35,7 @@ import io.element.android.libraries.designsystem.theme.components.Text * @param subTitle the subtitle to display * @param iconStyle the style of the [BigIcon] to display * @param modifier the modifier to apply to this layout + * @param showBetaLabel whether to show a "BETA" label next to the title */ @Composable fun IconTitleSubtitleMolecule( @@ -39,6 +43,7 @@ fun IconTitleSubtitleMolecule( subTitle: String?, iconStyle: BigIcon.Style, modifier: Modifier = Modifier, + showBetaLabel: Boolean = false, ) { Column(modifier) { BigIcon( @@ -46,17 +51,25 @@ fun IconTitleSubtitleMolecule( style = iconStyle, ) Spacer(modifier = Modifier.height(16.dp)) - Text( - text = title, - modifier = Modifier - .fillMaxWidth() - .semantics { - heading() - }, - textAlign = TextAlign.Center, - style = ElementTheme.typography.fontHeadingMdBold, - color = ElementTheme.colors.textPrimary, - ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally) + ) { + Text( + text = title, + modifier = Modifier + .semantics { + heading() + }, + textAlign = TextAlign.Center, + style = ElementTheme.typography.fontHeadingMdBold, + color = ElementTheme.colors.textPrimary, + ) + if (showBetaLabel) { + BetaLabel() + } + } if (subTitle != null) { Spacer(Modifier.height(8.dp)) Text( From 9f71bc4575e0451f2aabb803afd041bc3ca25475 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 22:06:21 +0200 Subject: [PATCH 14/73] Add a way to use the primary color for the icon. --- .../android/libraries/designsystem/components/BigIcon.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt index f469555ee4..78a4d32e44 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt @@ -53,11 +53,13 @@ object BigIcon { * @param vectorIcon the [ImageVector] to display * @param contentDescription the content description of the icon, if any. It defaults to `null` * @param useCriticalTint whether the icon and background should be rendered using critical tint + * @param usePrimaryTint whether the icon should be rendered using primary tint */ data class Default( val vectorIcon: ImageVector, val contentDescription: String? = null, val useCriticalTint: Boolean = false, + val usePrimaryTint: Boolean = false, ) : Style /** @@ -143,6 +145,8 @@ object BigIcon { val iconTint = when (style) { is Style.Default -> if (style.useCriticalTint) { ElementTheme.colors.iconCriticalPrimary + } else if (style.usePrimaryTint) { + ElementTheme.colors.iconPrimary } else { ElementTheme.colors.iconSecondary } From 2907f762f62a6128fc5d6a287504b4311afb1b74 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 23:13:43 +0200 Subject: [PATCH 15/73] Announcement for Spaces --- appnav/build.gradle.kts | 1 + .../io/element/android/appnav/RootFlowNode.kt | 5 + .../android/appnav/root/RootPresenter.kt | 4 + .../element/android/appnav/root/RootState.kt | 2 + .../android/appnav/root/RootStateProvider.kt | 2 + .../element/android/appnav/root/RootView.kt | 8 + .../android/appnav/RootPresenterTest.kt | 2 + features/announcement/api/build.gradle.kts | 13 ++ .../announcement/api/AnnouncementService.kt | 21 +++ .../announcement/api/AnnouncementState.kt | 18 ++ features/announcement/impl/build.gradle.kts | 36 ++++ .../impl/AnnouncementPresenter.kt | 35 ++++ .../impl/DefaultAnnouncementService.kt | 55 ++++++ .../impl/di/AnnouncementModule.kt | 23 +++ .../impl/spaces/SpaceAnnouncementEvents.kt | 12 ++ .../impl/spaces/SpaceAnnouncementNode.kt | 35 ++++ .../impl/spaces/SpaceAnnouncementPresenter.kt | 42 +++++ .../impl/spaces/SpaceAnnouncementState.kt | 14 ++ .../spaces/SpaceAnnouncementStateProvider.kt | 27 +++ .../impl/spaces/SpaceAnnouncementView.kt | 165 ++++++++++++++++++ .../impl/store/AnnouncementStore.kt | 23 +++ .../impl/store/DefaultAnnouncementStore.kt | 44 +++++ .../impl/src/main/res/values/localazy.xml | 11 ++ .../impl/AnnouncementPresenterTest.kt | 18 ++ features/announcement/test/build.gradle.kts | 19 ++ .../test/logs/FakeAnnouncementService.kt | 28 +++ features/home/impl/build.gradle.kts | 2 + .../features/home/impl/HomePresenter.kt | 7 +- .../features/home/impl/HomePresenterTest.kt | 13 ++ tools/localazy/config.json | 6 + 30 files changed, 690 insertions(+), 1 deletion(-) create mode 100644 features/announcement/api/build.gradle.kts create mode 100644 features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt create mode 100644 features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt create mode 100644 features/announcement/impl/build.gradle.kts create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/AnnouncementStore.kt create mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt create mode 100644 features/announcement/impl/src/main/res/values/localazy.xml create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt create mode 100644 features/announcement/test/build.gradle.kts create mode 100644 features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index 7f487a1e63..063e26b9da 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { implementation(libs.coil) + implementation(projects.features.announcement.api) implementation(projects.features.ftue.api) implementation(projects.features.share.api) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 7f5cb13246..c01b42af37 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -34,6 +34,7 @@ import io.element.android.appnav.intent.ResolvedIntent import io.element.android.appnav.root.RootNavStateFlowFactory import io.element.android.appnav.root.RootPresenter import io.element.android.appnav.root.RootView +import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.login.api.LoginParams import io.element.android.features.login.api.accesscontrol.AccountProviderAccessControl import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint @@ -81,6 +82,7 @@ class RootFlowNode( private val oidcActionFlow: OidcActionFlow, private val bugReporter: BugReporter, private val featureFlagService: FeatureFlagService, + private val announcementService: AnnouncementService, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.SplashScreen, @@ -172,6 +174,9 @@ class RootFlowNode( state = state, modifier = modifier, onOpenBugReport = this::onOpenBugReport, + announcementRenderer = { state, announcementModifier -> + announcementService.Render(state, announcementModifier) + } ) { val backstackSlider = rememberBackstackSlider( transitionSpec = { spring(stiffness = Spring.StiffnessMediumLow) }, diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt index d987c2a7ec..928e551a56 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.SuperProperties +import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionState import io.element.android.features.rageshake.api.detection.RageshakeDetectionState import io.element.android.libraries.architecture.Presenter @@ -24,6 +25,7 @@ import io.element.android.services.apperror.api.AppErrorStateService class RootPresenter( private val crashDetectionPresenter: Presenter, private val rageshakeDetectionPresenter: Presenter, + private val announcementPresenter: Presenter, private val appErrorStateService: AppErrorStateService, private val analyticsService: AnalyticsService, private val sdkMetadata: SdkMetadata, @@ -32,6 +34,7 @@ class RootPresenter( override fun present(): RootState { val rageshakeDetectionState = rageshakeDetectionPresenter.present() val crashDetectionState = crashDetectionPresenter.present() + val announcementState = announcementPresenter.present() val appErrorState by appErrorStateService.appErrorStateFlow.collectAsState() LaunchedEffect(Unit) { @@ -48,6 +51,7 @@ class RootPresenter( rageshakeDetectionState = rageshakeDetectionState, crashDetectionState = crashDetectionState, errorState = appErrorState, + announcementState = announcementState, ) } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt index 3ea7362efa..5ab995246f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt @@ -8,6 +8,7 @@ package io.element.android.appnav.root import androidx.compose.runtime.Immutable +import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionState import io.element.android.features.rageshake.api.detection.RageshakeDetectionState import io.element.android.services.apperror.api.AppErrorState @@ -17,4 +18,5 @@ data class RootState( val rageshakeDetectionState: RageshakeDetectionState, val crashDetectionState: CrashDetectionState, val errorState: AppErrorState, + val announcementState: AnnouncementState, ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt index 4d84e06070..896e62d820 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt @@ -8,6 +8,7 @@ package io.element.android.appnav.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.announcement.api.anAnnouncementState import io.element.android.features.rageshake.api.crash.aCrashDetectionState import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState import io.element.android.services.apperror.api.AppErrorState @@ -33,5 +34,6 @@ open class RootStateProvider : PreviewParameterProvider { fun aRootState() = RootState( rageshakeDetectionState = aRageshakeDetectionState(), crashDetectionState = aCrashDetectionState(), + announcementState = anAnnouncementState(), errorState = AppErrorState.NoError, ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt index bd7db5e9c2..275ccaae84 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionEvents import io.element.android.features.rageshake.api.crash.CrashDetectionView import io.element.android.features.rageshake.api.detection.RageshakeDetectionEvents @@ -27,6 +28,7 @@ import io.element.android.services.apperror.impl.AppErrorView fun RootView( state: RootState, onOpenBugReport: () -> Unit, + announcementRenderer: @Composable (AnnouncementState, Modifier) -> Unit, modifier: Modifier = Modifier, children: @Composable BoxScope.() -> Unit, ) { @@ -43,6 +45,11 @@ fun RootView( onOpenBugReport.invoke() } + announcementRenderer( + state.announcementState, + Modifier, + ) + RageshakeDetectionView( state = state.rageshakeDetectionState, onOpenBugReport = ::onOpenBugReport, @@ -63,6 +70,7 @@ internal fun RootViewPreview(@PreviewParameter(RootStateProvider::class) rootSta RootView( state = rootState, onOpenBugReport = {}, + announcementRenderer = { _, _ -> }, ) { Text("Children") } diff --git a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt index 2a343a1592..9d0d1e9572 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt @@ -12,6 +12,7 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.appnav.root.RootPresenter +import io.element.android.features.announcement.api.anAnnouncementState import io.element.android.features.rageshake.api.crash.aCrashDetectionState import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState import io.element.android.libraries.matrix.test.FakeSdkMetadata @@ -71,6 +72,7 @@ class RootPresenterTest { return RootPresenter( crashDetectionPresenter = { aCrashDetectionState() }, rageshakeDetectionPresenter = { aRageshakeDetectionState() }, + announcementPresenter = { anAnnouncementState() }, appErrorStateService = appErrorService, analyticsService = FakeAnalyticsService(), sdkMetadata = FakeSdkMetadata("sha") diff --git a/features/announcement/api/build.gradle.kts b/features/announcement/api/build.gradle.kts new file mode 100644 index 0000000000..0fa87f039e --- /dev/null +++ b/features/announcement/api/build.gradle.kts @@ -0,0 +1,13 @@ +/* + * 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. + */ +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.features.announcement.api" +} diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt new file mode 100644 index 0000000000..abd50aef3b --- /dev/null +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt @@ -0,0 +1,21 @@ +/* + * 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.announcement.api + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +interface AnnouncementService { + suspend fun onEnteringSpaceTab() + + @Composable + fun Render( + state: AnnouncementState, + modifier: Modifier, + ) +} diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt new file mode 100644 index 0000000000..eccdbd237c --- /dev/null +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt @@ -0,0 +1,18 @@ +/* + * 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.announcement.api + +data class AnnouncementState( + val showSpaceAnnouncement: Boolean, +) + +fun anAnnouncementState( + showSpaceAnnouncement: Boolean = false, +) = AnnouncementState( + showSpaceAnnouncement = showSpaceAnnouncement, +) diff --git a/features/announcement/impl/build.gradle.kts b/features/announcement/impl/build.gradle.kts new file mode 100644 index 0000000000..0ef6d09061 --- /dev/null +++ b/features/announcement/impl/build.gradle.kts @@ -0,0 +1,36 @@ +import extension.setupDependencyInjection +import extension.testCommonDependencies + +/* + * 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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.features.announcement.impl" + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } +} + +setupDependencyInjection() + +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.preferences.api) + implementation(projects.libraries.uiStrings) + api(projects.features.announcement.api) + implementation(libs.androidx.datastore.preferences) + + testCommonDependencies(libs) +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt new file mode 100644 index 0000000000..435d69d1f5 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt @@ -0,0 +1,35 @@ +/* + * 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.announcement.impl + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.api.AnnouncementState +import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.libraries.architecture.Presenter +import kotlinx.coroutines.flow.map + +@Inject +class AnnouncementPresenter( + private val announcementStore: AnnouncementStore, +) : Presenter { + @Composable + override fun present(): AnnouncementState { + val showSpaceAnnouncement by remember { + announcementStore.spaceAnnouncementFlow().map { + it == AnnouncementStore.SpaceAnnouncement.Show + } + }.collectAsState(false) + return AnnouncementState( + showSpaceAnnouncement = showSpaceAnnouncement, + ) + } +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt new file mode 100644 index 0000000000..fb82246a3c --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt @@ -0,0 +1,55 @@ +/* + * 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.announcement.impl + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.api.AnnouncementService +import io.element.android.features.announcement.api.AnnouncementState +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementPresenter +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementView +import io.element.android.features.announcement.impl.store.AnnouncementStore +import kotlinx.coroutines.flow.first + +@ContributesBinding(AppScope::class) +@Inject +class DefaultAnnouncementService( + private val announcementStore: AnnouncementStore, + private val spaceAnnouncementPresenter: SpaceAnnouncementPresenter, +) : AnnouncementService { + override suspend fun onEnteringSpaceTab() { + val currentValue = announcementStore.spaceAnnouncementFlow().first() + if (currentValue == AnnouncementStore.SpaceAnnouncement.NeverShown) { + announcementStore.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Show) + } + } + + @Composable + override fun Render(state: AnnouncementState, modifier: Modifier) { + Box(modifier = modifier.fillMaxSize()) { + AnimatedVisibility( + visible = state.showSpaceAnnouncement, + enter = fadeIn(), + exit = fadeOut(), + ) { + val spaceAnnouncementState = spaceAnnouncementPresenter.present() + SpaceAnnouncementView( + state = spaceAnnouncementState, + ) + } + } + } +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt new file mode 100644 index 0000000000..64998dfe1a --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt @@ -0,0 +1,23 @@ +/* + * 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.announcement.impl.di + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.BindingContainer +import dev.zacsweers.metro.Binds +import dev.zacsweers.metro.ContributesTo +import io.element.android.features.announcement.api.AnnouncementState +import io.element.android.features.announcement.impl.AnnouncementPresenter +import io.element.android.libraries.architecture.Presenter + +@ContributesTo(AppScope::class) +@BindingContainer +interface AnnouncementModule { + @Binds + fun bindAnnouncementPresenter(presenter: AnnouncementPresenter): Presenter +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt new file mode 100644 index 0000000000..9741608b1e --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt @@ -0,0 +1,12 @@ +/* + * 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.announcement.impl.spaces + +sealed interface SpaceAnnouncementEvents { + data object Continue : SpaceAnnouncementEvents +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt new file mode 100644 index 0000000000..ba8f74d803 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt @@ -0,0 +1,35 @@ +/* + * 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.announcement.impl.spaces + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class SpaceAnnouncementNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: SpaceAnnouncementPresenter, +) : Node(buildContext, plugins = plugins) { + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + SpaceAnnouncementView( + state = state, + modifier = modifier, + ) + } +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt new file mode 100644 index 0000000000..dbe619a867 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt @@ -0,0 +1,42 @@ +/* + * 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.announcement.impl.spaces + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.features.announcement.impl.store.AnnouncementStore.SpaceAnnouncement +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.meta.BuildMeta +import kotlinx.coroutines.launch + +@Inject +class SpaceAnnouncementPresenter( + private val buildMeta: BuildMeta, + private val announcementStore: AnnouncementStore, +) : Presenter { + @Composable + override fun present(): SpaceAnnouncementState { + val localCoroutineScope = rememberCoroutineScope() + + fun handleEvents(event: SpaceAnnouncementEvents) { + when (event) { + SpaceAnnouncementEvents.Continue -> localCoroutineScope.launch { + announcementStore.setSpaceAnnouncementValue(SpaceAnnouncement.Shown) + } + } + } + + return SpaceAnnouncementState( + applicationName = buildMeta.applicationName, + desktopApplicationName = buildMeta.desktopApplicationName, + eventSink = ::handleEvents + ) + } +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt new file mode 100644 index 0000000000..f02519a405 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt @@ -0,0 +1,14 @@ +/* + * 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.announcement.impl.spaces + +data class SpaceAnnouncementState( + val applicationName: String, + val desktopApplicationName: String, + val eventSink: (SpaceAnnouncementEvents) -> Unit +) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt new file mode 100644 index 0000000000..0eb2e8ff48 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt @@ -0,0 +1,27 @@ +/* + * 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.announcement.impl.spaces + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class SpaceAnnouncementStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aSpaceAnnouncementState(), + ) +} + +fun aSpaceAnnouncementState( + applicationName: String = "Element", + desktopApplicationName: String = "Element", + eventSink: (SpaceAnnouncementEvents) -> Unit = {}, +) = SpaceAnnouncementState( + applicationName = applicationName, + desktopApplicationName = desktopApplicationName, + eventSink = eventSink, +) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt new file mode 100644 index 0000000000..58799c05bd --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt @@ -0,0 +1,165 @@ +/* + * 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.announcement.impl.spaces + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.announcement.impl.R +import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem +import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism +import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.persistentListOf + +/** + * Ref: https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=4593-40181 + */ +@Composable +fun SpaceAnnouncementView( + state: SpaceAnnouncementState, + modifier: Modifier = Modifier, +) { + val eventSink = state.eventSink + + fun onContinue() { + eventSink(SpaceAnnouncementEvents.Continue) + } + + BackHandler { + state.eventSink(SpaceAnnouncementEvents.Continue) + } + HeaderFooterPage( + modifier = modifier, + isScrollable = true, + contentPadding = PaddingValues(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 24.dp), + header = { + SpaceAnnouncementHeader(state = state) + }, + content = { + SpaceAnnouncementContent( + state = state, + modifier = Modifier.padding(horizontal = 8.dp), + ) + }, + footer = { + SpaceAnnouncementFooter( + onContinue = ::onContinue, + ) + } + ) +} + +@Composable +private fun SpaceAnnouncementHeader( + state: SpaceAnnouncementState, + modifier: Modifier = Modifier, +) { + IconTitleSubtitleMolecule( + modifier = modifier.padding(top = 16.dp, bottom = 16.dp), + title = stringResource(id = R.string.screen_space_announcement_title), + showBetaLabel = true, + subTitle = stringResource( + id = R.string.screen_space_announcement_subtitle, + state.applicationName + ), + iconStyle = BigIcon.Style.Default( + vectorIcon = CompoundIcons.WorkspaceSolid(), + usePrimaryTint = true, + ), + ) +} + +@Composable +private fun SpaceAnnouncementContent( + state: SpaceAnnouncementState, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier.fillMaxSize(), + ) { + InfoListOrganism( + modifier = Modifier.fillMaxWidth(), + items = persistentListOf( + InfoListItem( + message = stringResource(id = R.string.screen_space_announcement_item1, state.desktopApplicationName), + iconVector = CompoundIcons.VisibilityOn(), + ), + InfoListItem( + message = stringResource(id = R.string.screen_space_announcement_item2), + iconVector = CompoundIcons.Email(), + ), + InfoListItem( + message = stringResource(id = R.string.screen_space_announcement_item3), + iconVector = CompoundIcons.Search(), + ), + InfoListItem( + message = stringResource(id = R.string.screen_space_announcement_item4), + iconVector = CompoundIcons.Leave(), + ), + InfoListItem( + message = stringResource(id = R.string.screen_space_announcement_item5), + iconVector = CompoundIcons.Explore(), + ), + ), + textStyle = ElementTheme.typography.fontBodyLgMedium, + iconTint = ElementTheme.colors.iconSecondary, + iconSize = 24.dp + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp), + text = stringResource(id = R.string.screen_space_announcement_notice), + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun SpaceAnnouncementFooter( + onContinue: () -> Unit, +) { + ButtonColumnMolecule( + modifier = Modifier.padding(bottom = 8.dp) + ) { + Button( + text = stringResource(id = CommonStrings.action_continue), + onClick = onContinue, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +@PreviewsDayNight +@Composable +internal fun SpaceAnnouncementViewPreview(@PreviewParameter(SpaceAnnouncementStateProvider::class) state: SpaceAnnouncementState) = ElementPreview { + SpaceAnnouncementView( + state = state, + ) +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/AnnouncementStore.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/AnnouncementStore.kt new file mode 100644 index 0000000000..dd12120d23 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/AnnouncementStore.kt @@ -0,0 +1,23 @@ +/* + * 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.announcement.impl.store + +import kotlinx.coroutines.flow.Flow + +interface AnnouncementStore { + suspend fun setSpaceAnnouncementValue(value: SpaceAnnouncement) + fun spaceAnnouncementFlow(): Flow + + suspend fun reset() + + enum class SpaceAnnouncement { + NeverShown, + Show, + Shown, + } +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt new file mode 100644 index 0000000000..922a4aaaa7 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt @@ -0,0 +1,44 @@ +/* + * 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.announcement.impl.store + +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +private val spaceAnnouncementKey = intPreferencesKey("spaceAnnouncement") + +@ContributesBinding(AppScope::class) +@Inject +class DefaultAnnouncementStore( + preferenceDataStoreFactory: PreferenceDataStoreFactory, +) : AnnouncementStore { + private val store = preferenceDataStoreFactory.create("elementx_announcement") + + override suspend fun setSpaceAnnouncementValue(value: AnnouncementStore.SpaceAnnouncement) { + store.edit { + it[spaceAnnouncementKey] = value.ordinal + } + } + + override fun spaceAnnouncementFlow(): Flow { + return store.data.map { prefs -> + val ordinal = prefs[spaceAnnouncementKey] ?: AnnouncementStore.SpaceAnnouncement.NeverShown.ordinal + AnnouncementStore.SpaceAnnouncement.entries.getOrElse(ordinal) { AnnouncementStore.SpaceAnnouncement.NeverShown } + } + } + + override suspend fun reset() { + store.edit { it.clear() } + } +} diff --git a/features/announcement/impl/src/main/res/values/localazy.xml b/features/announcement/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..b995021dfd --- /dev/null +++ b/features/announcement/impl/src/main/res/values/localazy.xml @@ -0,0 +1,11 @@ + + + "View spaces you’ve created or joined on %1$s desktop" + "Accept or decline invites to spaces" + "Discover any rooms you can join in your spaces" + "Leave any spaces you’ve joined" + "Join public spaces" + "More features will be added in the future, such as creating or managing spaces on mobile." + "Welcome to the beta version of Spaces on %1$s mobile! With this first version you can:" + "Introducing Spaces" + diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt new file mode 100644 index 0000000000..5bfa74bc27 --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt @@ -0,0 +1,18 @@ +/* + * 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.rageshake.impl + +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class AnnouncementPresenterTest { + @Test + fun `present - initial test`() = runTest { + // TODO + } +} diff --git a/features/announcement/test/build.gradle.kts b/features/announcement/test/build.gradle.kts new file mode 100644 index 0000000000..9387dc0caf --- /dev/null +++ b/features/announcement/test/build.gradle.kts @@ -0,0 +1,19 @@ +/* + * 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. + */ +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.features.announcement.test" +} + +dependencies { + implementation(projects.features.announcement.api) + implementation(libs.coroutines.core) + implementation(projects.tests.testutils) +} diff --git a/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt new file mode 100644 index 0000000000..3d3bbfcaba --- /dev/null +++ b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2024 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.rageshake.test.logs + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.element.android.features.announcement.api.AnnouncementService +import io.element.android.features.announcement.api.AnnouncementState +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeAnnouncementService( + val onEnteringSpaceTabResult: () -> Unit = { lambdaError() }, + val renderResult: (AnnouncementState, Modifier) -> Unit = { _, _ -> lambdaError() }, +) : AnnouncementService { + override suspend fun onEnteringSpaceTab() { + onEnteringSpaceTabResult() + } + + @Composable + override fun Render(state: AnnouncementState, modifier: Modifier) { + renderResult(state, modifier) + } +} diff --git a/features/home/impl/build.gradle.kts b/features/home/impl/build.gradle.kts index 2bf09c9398..9a29532ef0 100644 --- a/features/home/impl/build.gradle.kts +++ b/features/home/impl/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(projects.libraries.permissions.noop) implementation(projects.libraries.preferences.api) implementation(projects.libraries.push.api) + implementation(projects.features.announcement.api) implementation(projects.features.invite.api) implementation(projects.features.networkmonitor.api) implementation(projects.features.logout.api) @@ -60,6 +61,7 @@ dependencies { api(projects.features.home.api) testCommonDependencies(libs, true) + testImplementation(projects.features.announcement.test) testImplementation(projects.features.invite.test) testImplementation(projects.features.logout.test) testImplementation(projects.features.networkmonitor.test) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt index 653a7134f3..d5f3e68898 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.roomlist.RoomListState import io.element.android.features.home.impl.spaces.HomeSpacesState import io.element.android.features.logout.api.direct.DirectLogoutState @@ -47,6 +48,7 @@ class HomePresenter( private val rageshakeFeatureAvailability: RageshakeFeatureAvailability, private val featureFlagService: FeatureFlagService, private val sessionStore: SessionStore, + private val announcementService: AnnouncementService, ) : Presenter { private val currentUserWithNeighborsBuilder = CurrentUserWithNeighborsBuilder() @@ -84,7 +86,10 @@ class HomePresenter( fun handleEvents(event: HomeEvents) { when (event) { - is HomeEvents.SelectHomeNavigationBarItem -> { + is HomeEvents.SelectHomeNavigationBarItem -> coroutineState.launch { + if (event.item == HomeNavigationBarItem.Spaces) { + announcementService.onEnteringSpaceTab() + } currentHomeNavigationBarItemOrdinal = event.item.ordinal } is HomeEvents.SwitchToAccount -> coroutineState.launch { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt index 8e5b35de99..aa5a612760 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt @@ -11,11 +11,13 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.roomlist.aRoomListState import io.element.android.features.home.impl.spaces.HomeSpacesState import io.element.android.features.home.impl.spaces.aHomeSpacesState import io.element.android.features.logout.api.direct.aDirectLogoutState import io.element.android.features.rageshake.api.RageshakeFeatureAvailability +import io.element.android.features.rageshake.test.logs.FakeAnnouncementService import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -37,6 +39,7 @@ import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.libraries.sessionstorage.test.aSessionData import io.element.android.tests.testutils.MutablePresenter import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -165,10 +168,14 @@ class HomePresenterTest { @Test fun `present - NavigationBar change`() = runTest { + val onEnteringSpaceTabResult = lambdaRecorder { } val presenter = createHomePresenter( sessionStore = InMemorySessionStore( updateUserProfileResult = { _, _, _ -> }, ), + announcementService = FakeAnnouncementService( + onEnteringSpaceTabResult = onEnteringSpaceTabResult, + ) ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -178,6 +185,7 @@ class HomePresenterTest { initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) val finalState = awaitItem() assertThat(finalState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Spaces) + onEnteringSpaceTabResult.assertions().isCalledOnce() } } @@ -192,6 +200,9 @@ class HomePresenterTest { initialState = mapOf(FeatureFlags.Space.key to true), ), homeSpacesPresenter = homeSpacesPresenter, + announcementService = FakeAnnouncementService( + onEnteringSpaceTabResult = {}, + ) ) presenter.test { skipItems(1) @@ -222,6 +233,7 @@ internal fun createHomePresenter( featureFlagService: FeatureFlagService = FakeFeatureFlagService(), homeSpacesPresenter: Presenter = Presenter { aHomeSpacesState() }, sessionStore: SessionStore = InMemorySessionStore(), + announcementService: AnnouncementService = FakeAnnouncementService(), ) = HomePresenter( client = client, syncService = syncService, @@ -233,4 +245,5 @@ internal fun createHomePresenter( rageshakeFeatureAvailability = rageshakeFeatureAvailability, featureFlagService = featureFlagService, sessionStore = sessionStore, + announcementService = announcementService, ) diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 2afebbef4d..73347a5896 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -22,6 +22,12 @@ "settings_rageshake.*" ] }, + { + "name" : ":features:announcement:impl", + "includeRegex" : [ + "screen\\.space_announcement\\..*" + ] + }, { "name" : ":features:logout:impl", "includeRegex" : [ From 48bc32e48b0ba4bf2638b69af5e71ad6043a9da6 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 2 Oct 2025 22:32:40 +0000 Subject: [PATCH 16/73] Update screenshots --- ...announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png | 3 +++ ...nouncement.impl.spaces_SpaceAnnouncementView_Night_0_en.png | 3 +++ .../libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png | 3 +++ ...ibraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png new file mode 100644 index 0000000000..d162a35968 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbaf478329e93e8762e5063e984ca124ab15171950a354324d353cd8454d2d9d +size 65293 diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png new file mode 100644 index 0000000000..fef29ced8c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:036f5e862232821552b7a7a25d32de3d65b7de68a4c410231bcf300b8952d6dc +size 64055 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png new file mode 100644 index 0000000000..5b11b1434d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63de7652fe0a3f62ba1cbb00d3a5cb49e620552d8ebb07b9cab916c5ca810538 +size 5175 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png new file mode 100644 index 0000000000..2041b72844 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d71a95f7319fb5c73a456eeae3a0c8bd67c489c460620ad76516f33ca6de364 +size 4972 From 15896c2668869bd0c7411ff2e9d532ca1d1b16aa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 09:40:38 +0200 Subject: [PATCH 17/73] Add unit test on AnnouncementPresenter --- .../impl/AnnouncementPresenterTest.kt | 50 +++++++++++++++++++ .../impl/store/InMemoryAnnouncementStore.kt | 29 +++++++++++ .../impl/AnnouncementPresenterTest.kt | 18 ------- 3 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt delete mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt new file mode 100644 index 0000000000..87cd68a405 --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt @@ -0,0 +1,50 @@ +/* + * 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.announcement.impl + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class AnnouncementPresenterTest { + @Test + fun `present - initial state`() = runTest { + val presenter = createAnnouncementPresenter() + presenter.test { + val state = awaitItem() + assertThat(state.showSpaceAnnouncement).isFalse() + } + } + + @Test + fun `present - showSpaceAnnouncement value depends on the value in the store`() = runTest { + val store = InMemoryAnnouncementStore() + val presenter = createAnnouncementPresenter( + announcementStore = store, + ) + presenter.test { + val state = awaitItem() + assertThat(state.showSpaceAnnouncement).isFalse() + store.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Show) + val updatedState = awaitItem() + assertThat(updatedState.showSpaceAnnouncement).isTrue() + store.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Shown) + val finalState = awaitItem() + assertThat(finalState.showSpaceAnnouncement).isFalse() + } + } +} + +private fun createAnnouncementPresenter( + announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), +) = AnnouncementPresenter( + announcementStore = announcementStore, +) diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt new file mode 100644 index 0000000000..0f99ef66bd --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt @@ -0,0 +1,29 @@ +/* + * 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.announcement.impl.store + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +class InMemoryAnnouncementStore( + initialSpaceAnnouncement: AnnouncementStore.SpaceAnnouncement = AnnouncementStore.SpaceAnnouncement.NeverShown, +) : AnnouncementStore { + private val spaceAnnouncement = MutableStateFlow(initialSpaceAnnouncement) + override suspend fun setSpaceAnnouncementValue(value: AnnouncementStore.SpaceAnnouncement) { + spaceAnnouncement.value = value + } + + override fun spaceAnnouncementFlow(): Flow { + return spaceAnnouncement.asStateFlow() + } + + override suspend fun reset() { + spaceAnnouncement.value = AnnouncementStore.SpaceAnnouncement.NeverShown + } +} diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt deleted file mode 100644 index 5bfa74bc27..0000000000 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/rageshake/impl/AnnouncementPresenterTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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.rageshake.impl - -import kotlinx.coroutines.test.runTest -import org.junit.Test - -class AnnouncementPresenterTest { - @Test - fun `present - initial test`() = runTest { - // TODO - } -} From 831eaca43d04268392c6222cedfad28c206bfe3a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 09:54:42 +0200 Subject: [PATCH 18/73] Add unit test on SpaceAnnouncementPresenter --- features/announcement/impl/build.gradle.kts | 1 + .../spaces/SpaceAnnouncementPresenterTest.kt | 57 +++++++++++++++++++ .../android/libraries/matrix/test/TestData.kt | 1 + 3 files changed, 59 insertions(+) create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt diff --git a/features/announcement/impl/build.gradle.kts b/features/announcement/impl/build.gradle.kts index 0ef6d09061..e9f653cb4c 100644 --- a/features/announcement/impl/build.gradle.kts +++ b/features/announcement/impl/build.gradle.kts @@ -33,4 +33,5 @@ dependencies { implementation(libs.androidx.datastore.preferences) testCommonDependencies(libs) + testImplementation(projects.libraries.matrix.test) } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt new file mode 100644 index 0000000000..c3ab3a410c --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt @@ -0,0 +1,57 @@ +/* + * 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.announcement.impl.spaces + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.matrix.test.AN_APPLICATION_NAME +import io.element.android.libraries.matrix.test.AN_APPLICATION_NAME_DESKTOP +import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.tests.testutils.test +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class SpaceAnnouncementPresenterTest { + @Test + fun `present - initial state`() = runTest { + val presenter = createSpaceAnnouncementPresenter() + presenter.test { + val state = awaitItem() + assertThat(state.applicationName).isEqualTo(AN_APPLICATION_NAME) + assertThat(state.desktopApplicationName).isEqualTo(AN_APPLICATION_NAME_DESKTOP) + } + } + + @Test + fun `present - when user continues, the store is updated`() = runTest { + val store = InMemoryAnnouncementStore() + val presenter = createSpaceAnnouncementPresenter( + announcementStore = store, + ) + presenter.test { + assertThat(store.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.NeverShown) + val state = awaitItem() + state.eventSink(SpaceAnnouncementEvents.Continue) + assertThat(store.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.Shown) + } + } +} + +private fun createSpaceAnnouncementPresenter( + buildMeta: BuildMeta = aBuildMeta( + applicationName = AN_APPLICATION_NAME, + desktopApplicationName = AN_APPLICATION_NAME_DESKTOP, + ), + announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), +) = SpaceAnnouncementPresenter( + buildMeta = buildMeta, + announcementStore = announcementStore, +) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index ed18a5ebd9..f05f6958c0 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -26,6 +26,7 @@ const val A_PASSWORD = "password" const val A_PASSPHRASE = "passphrase" const val A_SECRET = "secret" const val AN_APPLICATION_NAME = "AppName" +const val AN_APPLICATION_NAME_DESKTOP = "AppNameDesktop" val A_USER_ID = UserId("@alice:server.org") val A_USER_ID_2 = UserId("@bob:server.org") From c39f1f402fd3c4ae185e6ff5d215de711dfdd427 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 10:00:22 +0200 Subject: [PATCH 19/73] Remove unused Node --- .../impl/spaces/SpaceAnnouncementNode.kt | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt deleted file mode 100644 index ba8f74d803..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementNode.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.announcement.impl.spaces - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin -import dev.zacsweers.metro.Assisted -import dev.zacsweers.metro.AssistedInject -import io.element.android.annotations.ContributesNode -import io.element.android.libraries.di.SessionScope - -@ContributesNode(SessionScope::class) -@AssistedInject -class SpaceAnnouncementNode( - @Assisted buildContext: BuildContext, - @Assisted plugins: List, - private val presenter: SpaceAnnouncementPresenter, -) : Node(buildContext, plugins = plugins) { - @Composable - override fun View(modifier: Modifier) { - val state = presenter.present() - SpaceAnnouncementView( - state = state, - modifier = modifier, - ) - } -} From a831412946f60514a4c65384a9319b59ae4c2ee1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 10:11:58 +0200 Subject: [PATCH 20/73] Add test on DefaultAnnouncementService --- .../impl/DefaultAnnouncementService.kt | 5 ++- .../impl/di/AnnouncementModule.kt | 5 +++ .../impl/DefaultAnnouncementServiceTest.kt | 44 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt index fb82246a3c..a5ebb1716a 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt @@ -19,16 +19,17 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.announcement.api.AnnouncementState -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementPresenter +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementView import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.flow.first @ContributesBinding(AppScope::class) @Inject class DefaultAnnouncementService( private val announcementStore: AnnouncementStore, - private val spaceAnnouncementPresenter: SpaceAnnouncementPresenter, + private val spaceAnnouncementPresenter: Presenter, ) : AnnouncementService { override suspend fun onEnteringSpaceTab() { val currentValue = announcementStore.spaceAnnouncementFlow().first() diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt index 64998dfe1a..282f653aa7 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt @@ -13,6 +13,8 @@ import dev.zacsweers.metro.Binds import dev.zacsweers.metro.ContributesTo import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.announcement.impl.AnnouncementPresenter +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementPresenter +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.libraries.architecture.Presenter @ContributesTo(AppScope::class) @@ -20,4 +22,7 @@ import io.element.android.libraries.architecture.Presenter interface AnnouncementModule { @Binds fun bindAnnouncementPresenter(presenter: AnnouncementPresenter): Presenter + + @Binds + fun bindSpaceAnnouncementPresenter(presenter: SpaceAnnouncementPresenter): Presenter } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt new file mode 100644 index 0000000000..5882549785 --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt @@ -0,0 +1,44 @@ +/* + * 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.announcement.impl + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState +import io.element.android.features.announcement.impl.spaces.aSpaceAnnouncementState +import io.element.android.features.announcement.impl.store.AnnouncementStore +import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore +import io.element.android.libraries.architecture.Presenter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DefaultAnnouncementServiceTest { + @Test + fun `when entering space tab, space announcement is set to show only if it was never shown`() = runTest { + val announcementStore = InMemoryAnnouncementStore() + val sut = createDefaultAnnouncementService( + announcementStore = announcementStore, + ) + assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.NeverShown) + sut.onEnteringSpaceTab() + assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.Show) + // Simulate user close the announcement + announcementStore.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Shown) + // Entering again the space tab should not change the value + sut.onEnteringSpaceTab() + assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.Shown) + } + + private fun createDefaultAnnouncementService( + announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), + spaceAnnouncementPresenter: Presenter = Presenter { aSpaceAnnouncementState() }, + ) = DefaultAnnouncementService( + announcementStore = announcementStore, + spaceAnnouncementPresenter = spaceAnnouncementPresenter, + ) +} From e8e958137c90ccbca68af12d66d6d3e088f25158 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 10:52:45 +0200 Subject: [PATCH 21/73] Use onContinue method in the back handler --- .../announcement/impl/spaces/SpaceAnnouncementView.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt index 58799c05bd..7f0a7291a5 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt @@ -49,9 +49,7 @@ fun SpaceAnnouncementView( eventSink(SpaceAnnouncementEvents.Continue) } - BackHandler { - state.eventSink(SpaceAnnouncementEvents.Continue) - } + BackHandler(onBack = ::onContinue) HeaderFooterPage( modifier = modifier, isScrollable = true, From 26106365ef48f2e39ec42b89dac2ff2859323958 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 11:35:48 +0200 Subject: [PATCH 22/73] Add test on SpaceAnnouncementView --- features/announcement/impl/build.gradle.kts | 2 +- .../impl/spaces/SpaceAnnouncementViewTest.kt | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt diff --git a/features/announcement/impl/build.gradle.kts b/features/announcement/impl/build.gradle.kts index e9f653cb4c..222d080d6e 100644 --- a/features/announcement/impl/build.gradle.kts +++ b/features/announcement/impl/build.gradle.kts @@ -32,6 +32,6 @@ dependencies { api(projects.features.announcement.api) implementation(libs.androidx.datastore.preferences) - testCommonDependencies(libs) + testCommonDependencies(libs, true) testImplementation(projects.libraries.matrix.test) } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt new file mode 100644 index 0000000000..96b98668a4 --- /dev/null +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt @@ -0,0 +1,60 @@ +/* + * 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.announcement.impl.spaces + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EventsRecorder +import io.element.android.tests.testutils.clickOn +import io.element.android.tests.testutils.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SpaceAnnouncementViewTest { + @get:Rule val rule = createAndroidComposeRule() + + @Test + fun `clicking on back sends a SpaceAnnouncementEvents`() { + val eventsRecorder = EventsRecorder() + rule.setSpaceAnnouncementView( + aSpaceAnnouncementState( + eventSink = eventsRecorder, + ), + ) + rule.pressBackKey() + eventsRecorder.assertSingle(SpaceAnnouncementEvents.Continue) + } + + @Test + fun `clicking on Continue sends a SpaceAnnouncementEvents`() { + val eventsRecorder = EventsRecorder() + rule.setSpaceAnnouncementView( + aSpaceAnnouncementState( + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_continue) + eventsRecorder.assertSingle(SpaceAnnouncementEvents.Continue) + } +} + +private fun AndroidComposeTestRule.setSpaceAnnouncementView( + state: SpaceAnnouncementState, +) { + setContent { + SpaceAnnouncementView( + state = state, + ) + } +} From 93c273468ea3c40bcdf9ce67b36be90cadf3b79b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 11:57:06 +0200 Subject: [PATCH 23/73] Do not expose `AnnouncementState` in the api module --- .../kotlin/io/element/android/appnav/RootFlowNode.kt | 4 ++-- .../io/element/android/appnav/root/RootPresenter.kt | 4 ---- .../kotlin/io/element/android/appnav/root/RootState.kt | 2 -- .../element/android/appnav/root/RootStateProvider.kt | 2 -- .../kotlin/io/element/android/appnav/root/RootView.kt | 10 +++------- .../io/element/android/appnav/RootPresenterTest.kt | 2 -- .../features/announcement/api/AnnouncementService.kt | 1 - .../announcement/impl/AnnouncementPresenter.kt | 1 - .../features/announcement/impl}/AnnouncementState.kt | 2 +- .../announcement/impl/DefaultAnnouncementService.kt | 7 ++++--- .../announcement/impl/di/AnnouncementModule.kt | 2 +- .../impl/DefaultAnnouncementServiceTest.kt | 2 ++ .../rageshake/test/logs/FakeAnnouncementService.kt | 7 +++---- 13 files changed, 16 insertions(+), 30 deletions(-) rename features/announcement/{api/src/main/kotlin/io/element/android/features/announcement/api => impl/src/main/kotlin/io/element/android/features/announcement/impl}/AnnouncementState.kt (88%) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index c01b42af37..4498a44e07 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -174,8 +174,8 @@ class RootFlowNode( state = state, modifier = modifier, onOpenBugReport = this::onOpenBugReport, - announcementRenderer = { state, announcementModifier -> - announcementService.Render(state, announcementModifier) + announcementRenderer = { announcementModifier -> + announcementService.Render(announcementModifier) } ) { val backstackSlider = rememberBackstackSlider( diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt index 928e551a56..d987c2a7ec 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.SuperProperties -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionState import io.element.android.features.rageshake.api.detection.RageshakeDetectionState import io.element.android.libraries.architecture.Presenter @@ -25,7 +24,6 @@ import io.element.android.services.apperror.api.AppErrorStateService class RootPresenter( private val crashDetectionPresenter: Presenter, private val rageshakeDetectionPresenter: Presenter, - private val announcementPresenter: Presenter, private val appErrorStateService: AppErrorStateService, private val analyticsService: AnalyticsService, private val sdkMetadata: SdkMetadata, @@ -34,7 +32,6 @@ class RootPresenter( override fun present(): RootState { val rageshakeDetectionState = rageshakeDetectionPresenter.present() val crashDetectionState = crashDetectionPresenter.present() - val announcementState = announcementPresenter.present() val appErrorState by appErrorStateService.appErrorStateFlow.collectAsState() LaunchedEffect(Unit) { @@ -51,7 +48,6 @@ class RootPresenter( rageshakeDetectionState = rageshakeDetectionState, crashDetectionState = crashDetectionState, errorState = appErrorState, - announcementState = announcementState, ) } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt index 5ab995246f..3ea7362efa 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt @@ -8,7 +8,6 @@ package io.element.android.appnav.root import androidx.compose.runtime.Immutable -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionState import io.element.android.features.rageshake.api.detection.RageshakeDetectionState import io.element.android.services.apperror.api.AppErrorState @@ -18,5 +17,4 @@ data class RootState( val rageshakeDetectionState: RageshakeDetectionState, val crashDetectionState: CrashDetectionState, val errorState: AppErrorState, - val announcementState: AnnouncementState, ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt index 896e62d820..4d84e06070 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt @@ -8,7 +8,6 @@ package io.element.android.appnav.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.announcement.api.anAnnouncementState import io.element.android.features.rageshake.api.crash.aCrashDetectionState import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState import io.element.android.services.apperror.api.AppErrorState @@ -34,6 +33,5 @@ open class RootStateProvider : PreviewParameterProvider { fun aRootState() = RootState( rageshakeDetectionState = aRageshakeDetectionState(), crashDetectionState = aCrashDetectionState(), - announcementState = anAnnouncementState(), errorState = AppErrorState.NoError, ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt index 275ccaae84..2913407fc1 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt @@ -14,7 +14,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.PreviewParameter -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.rageshake.api.crash.CrashDetectionEvents import io.element.android.features.rageshake.api.crash.CrashDetectionView import io.element.android.features.rageshake.api.detection.RageshakeDetectionEvents @@ -28,7 +27,7 @@ import io.element.android.services.apperror.impl.AppErrorView fun RootView( state: RootState, onOpenBugReport: () -> Unit, - announcementRenderer: @Composable (AnnouncementState, Modifier) -> Unit, + announcementRenderer: @Composable (Modifier) -> Unit, modifier: Modifier = Modifier, children: @Composable BoxScope.() -> Unit, ) { @@ -45,10 +44,7 @@ fun RootView( onOpenBugReport.invoke() } - announcementRenderer( - state.announcementState, - Modifier, - ) + announcementRenderer(Modifier) RageshakeDetectionView( state = state.rageshakeDetectionState, @@ -70,7 +66,7 @@ internal fun RootViewPreview(@PreviewParameter(RootStateProvider::class) rootSta RootView( state = rootState, onOpenBugReport = {}, - announcementRenderer = { _, _ -> }, + announcementRenderer = { }, ) { Text("Children") } diff --git a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt index 9d0d1e9572..2a343a1592 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt @@ -12,7 +12,6 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.appnav.root.RootPresenter -import io.element.android.features.announcement.api.anAnnouncementState import io.element.android.features.rageshake.api.crash.aCrashDetectionState import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState import io.element.android.libraries.matrix.test.FakeSdkMetadata @@ -72,7 +71,6 @@ class RootPresenterTest { return RootPresenter( crashDetectionPresenter = { aCrashDetectionState() }, rageshakeDetectionPresenter = { aRageshakeDetectionState() }, - announcementPresenter = { anAnnouncementState() }, appErrorStateService = appErrorService, analyticsService = FakeAnalyticsService(), sdkMetadata = FakeSdkMetadata("sha") diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt index abd50aef3b..de822c8873 100644 --- a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt @@ -15,7 +15,6 @@ interface AnnouncementService { @Composable fun Render( - state: AnnouncementState, modifier: Modifier, ) } diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt index 435d69d1f5..76746bf44e 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import dev.zacsweers.metro.Inject -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.announcement.impl.store.AnnouncementStore import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.flow.map diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt similarity index 88% rename from features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt rename to features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt index eccdbd237c..c8ea728d64 100644 --- a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementState.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.announcement.api +package io.element.android.features.announcement.impl data class AnnouncementState( val showSpaceAnnouncement: Boolean, diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt index a5ebb1716a..ef6314b82e 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt @@ -18,7 +18,6 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import io.element.android.features.announcement.api.AnnouncementService -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementView import io.element.android.features.announcement.impl.store.AnnouncementStore @@ -29,6 +28,7 @@ import kotlinx.coroutines.flow.first @Inject class DefaultAnnouncementService( private val announcementStore: AnnouncementStore, + private val announcementPresenter: Presenter, private val spaceAnnouncementPresenter: Presenter, ) : AnnouncementService { override suspend fun onEnteringSpaceTab() { @@ -39,10 +39,11 @@ class DefaultAnnouncementService( } @Composable - override fun Render(state: AnnouncementState, modifier: Modifier) { + override fun Render(modifier: Modifier) { + val announcementState = announcementPresenter.present() Box(modifier = modifier.fillMaxSize()) { AnimatedVisibility( - visible = state.showSpaceAnnouncement, + visible = announcementState.showSpaceAnnouncement, enter = fadeIn(), exit = fadeOut(), ) { diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt index 282f653aa7..4fbc9118bc 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt @@ -11,8 +11,8 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.Binds import dev.zacsweers.metro.ContributesTo -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.features.announcement.impl.AnnouncementPresenter +import io.element.android.features.announcement.impl.AnnouncementState import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementPresenter import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.libraries.architecture.Presenter diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt index 5882549785..4e6249787a 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt @@ -36,9 +36,11 @@ class DefaultAnnouncementServiceTest { private fun createDefaultAnnouncementService( announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), + announcementPresenter: Presenter = Presenter { anAnnouncementState() }, spaceAnnouncementPresenter: Presenter = Presenter { aSpaceAnnouncementState() }, ) = DefaultAnnouncementService( announcementStore = announcementStore, + announcementPresenter = announcementPresenter, spaceAnnouncementPresenter = spaceAnnouncementPresenter, ) } diff --git a/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt index 3d3bbfcaba..a9f5452efc 100644 --- a/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt +++ b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt @@ -10,19 +10,18 @@ package io.element.android.features.rageshake.test.logs import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import io.element.android.features.announcement.api.AnnouncementService -import io.element.android.features.announcement.api.AnnouncementState import io.element.android.tests.testutils.lambda.lambdaError class FakeAnnouncementService( val onEnteringSpaceTabResult: () -> Unit = { lambdaError() }, - val renderResult: (AnnouncementState, Modifier) -> Unit = { _, _ -> lambdaError() }, + val renderResult: (Modifier) -> Unit = { lambdaError() }, ) : AnnouncementService { override suspend fun onEnteringSpaceTab() { onEnteringSpaceTabResult() } @Composable - override fun Render(state: AnnouncementState, modifier: Modifier) { - renderResult(state, modifier) + override fun Render(modifier: Modifier) { + renderResult(modifier) } } From d7f39c332f2ff65f059d08058ab9ad5daa9ec6e8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 12:03:06 +0200 Subject: [PATCH 24/73] Introduce Announcement enum. --- .../features/announcement/api/Announcement.kt | 12 ++++++++++++ .../features/announcement/api/AnnouncementService.kt | 2 +- .../announcement/impl/DefaultAnnouncementService.kt | 9 ++++++++- .../impl/DefaultAnnouncementServiceTest.kt | 7 ++++--- .../rageshake/test/logs/FakeAnnouncementService.kt | 7 ++++--- .../android/features/home/impl/HomePresenter.kt | 3 ++- .../android/features/home/impl/HomePresenterTest.kt | 11 +++++++---- 7 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt new file mode 100644 index 0000000000..96fd738903 --- /dev/null +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt @@ -0,0 +1,12 @@ +/* + * 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.announcement.api + +enum class Announcement { + Space, +} diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt index de822c8873..62944d727e 100644 --- a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/AnnouncementService.kt @@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier interface AnnouncementService { - suspend fun onEnteringSpaceTab() + suspend fun showAnnouncement(announcement: Announcement) @Composable fun Render( diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt index ef6314b82e..e9b6310544 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementView @@ -31,7 +32,13 @@ class DefaultAnnouncementService( private val announcementPresenter: Presenter, private val spaceAnnouncementPresenter: Presenter, ) : AnnouncementService { - override suspend fun onEnteringSpaceTab() { + override suspend fun showAnnouncement(announcement: Announcement) { + when (announcement) { + Announcement.Space -> showSpaceAnnouncement() + } + } + + private suspend fun showSpaceAnnouncement() { val currentValue = announcementStore.spaceAnnouncementFlow().first() if (currentValue == AnnouncementStore.SpaceAnnouncement.NeverShown) { announcementStore.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Show) diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt index 4e6249787a..74155ce13b 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt @@ -8,6 +8,7 @@ package io.element.android.features.announcement.impl import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState import io.element.android.features.announcement.impl.spaces.aSpaceAnnouncementState import io.element.android.features.announcement.impl.store.AnnouncementStore @@ -19,18 +20,18 @@ import org.junit.Test class DefaultAnnouncementServiceTest { @Test - fun `when entering space tab, space announcement is set to show only if it was never shown`() = runTest { + fun `when showing Space announcement, space announcement is set to show only if it was never shown`() = runTest { val announcementStore = InMemoryAnnouncementStore() val sut = createDefaultAnnouncementService( announcementStore = announcementStore, ) assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.NeverShown) - sut.onEnteringSpaceTab() + sut.showAnnouncement(Announcement.Space) assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.Show) // Simulate user close the announcement announcementStore.setSpaceAnnouncementValue(AnnouncementStore.SpaceAnnouncement.Shown) // Entering again the space tab should not change the value - sut.onEnteringSpaceTab() + sut.showAnnouncement(Announcement.Space) assertThat(announcementStore.spaceAnnouncementFlow().first()).isEqualTo(AnnouncementStore.SpaceAnnouncement.Shown) } diff --git a/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt index a9f5452efc..a9d56e975c 100644 --- a/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt +++ b/features/announcement/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeAnnouncementService.kt @@ -9,15 +9,16 @@ package io.element.android.features.rageshake.test.logs import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.tests.testutils.lambda.lambdaError class FakeAnnouncementService( - val onEnteringSpaceTabResult: () -> Unit = { lambdaError() }, + val showAnnouncementResult: (Announcement) -> Unit = { lambdaError() }, val renderResult: (Modifier) -> Unit = { lambdaError() }, ) : AnnouncementService { - override suspend fun onEnteringSpaceTab() { - onEnteringSpaceTabResult() + override suspend fun showAnnouncement(announcement: Announcement) { + showAnnouncementResult(announcement) } @Composable diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt index d5f3e68898..e3ca9612d1 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject +import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.roomlist.RoomListState import io.element.android.features.home.impl.spaces.HomeSpacesState @@ -88,7 +89,7 @@ class HomePresenter( when (event) { is HomeEvents.SelectHomeNavigationBarItem -> coroutineState.launch { if (event.item == HomeNavigationBarItem.Spaces) { - announcementService.onEnteringSpaceTab() + announcementService.showAnnouncement(Announcement.Space) } currentHomeNavigationBarItemOrdinal = event.item.ordinal } diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt index aa5a612760..8048564e2b 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt @@ -11,6 +11,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.roomlist.aRoomListState import io.element.android.features.home.impl.spaces.HomeSpacesState @@ -40,6 +41,7 @@ import io.element.android.libraries.sessionstorage.test.aSessionData import io.element.android.tests.testutils.MutablePresenter import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -168,13 +170,13 @@ class HomePresenterTest { @Test fun `present - NavigationBar change`() = runTest { - val onEnteringSpaceTabResult = lambdaRecorder { } + val showAnnouncementResult = lambdaRecorder { } val presenter = createHomePresenter( sessionStore = InMemorySessionStore( updateUserProfileResult = { _, _, _ -> }, ), announcementService = FakeAnnouncementService( - onEnteringSpaceTabResult = onEnteringSpaceTabResult, + showAnnouncementResult = showAnnouncementResult, ) ) moleculeFlow(RecompositionMode.Immediate) { @@ -185,7 +187,8 @@ class HomePresenterTest { initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) val finalState = awaitItem() assertThat(finalState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Spaces) - onEnteringSpaceTabResult.assertions().isCalledOnce() + showAnnouncementResult.assertions().isCalledOnce() + .with(value(Announcement.Space)) } } @@ -201,7 +204,7 @@ class HomePresenterTest { ), homeSpacesPresenter = homeSpacesPresenter, announcementService = FakeAnnouncementService( - onEnteringSpaceTabResult = {}, + showAnnouncementResult = {}, ) ) presenter.test { From 555beb1d3745bc8e74fdc267df6b1a3def1d4d37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 12:09:43 +0200 Subject: [PATCH 25/73] Improve code. --- .../src/main/kotlin/io/element/android/appnav/RootFlowNode.kt | 4 +--- .../main/kotlin/io/element/android/appnav/root/RootView.kt | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 4498a44e07..19290c5f8b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -174,9 +174,6 @@ class RootFlowNode( state = state, modifier = modifier, onOpenBugReport = this::onOpenBugReport, - announcementRenderer = { announcementModifier -> - announcementService.Render(announcementModifier) - } ) { val backstackSlider = rememberBackstackSlider( transitionSpec = { spring(stiffness = Spring.StiffnessMediumLow) }, @@ -192,6 +189,7 @@ class RootFlowNode( } } BackstackView(transitionHandler = transitionHandler) + announcementService.Render(Modifier) } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt index 2913407fc1..bd7db5e9c2 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt @@ -27,7 +27,6 @@ import io.element.android.services.apperror.impl.AppErrorView fun RootView( state: RootState, onOpenBugReport: () -> Unit, - announcementRenderer: @Composable (Modifier) -> Unit, modifier: Modifier = Modifier, children: @Composable BoxScope.() -> Unit, ) { @@ -44,8 +43,6 @@ fun RootView( onOpenBugReport.invoke() } - announcementRenderer(Modifier) - RageshakeDetectionView( state = state.rageshakeDetectionState, onOpenBugReport = ::onOpenBugReport, @@ -66,7 +63,6 @@ internal fun RootViewPreview(@PreviewParameter(RootStateProvider::class) rootSta RootView( state = rootState, onOpenBugReport = {}, - announcementRenderer = { }, ) { Text("Children") } From e69dd054346fe4d06c63d56bc23220c919976cb9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 14:43:47 +0200 Subject: [PATCH 26/73] Improve LeaveSpacePresenter and add a retry mechanism if loading the rooms fails. --- .../space/impl/leave/LeaveSpaceEvents.kt | 1 + .../space/impl/leave/LeaveSpacePresenter.kt | 77 +++++++++++-------- .../space/impl/leave/LeaveSpaceView.kt | 4 +- .../impl/leave/LeaveSpacePresenterTest.kt | 10 ++- 4 files changed, 57 insertions(+), 35 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceEvents.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceEvents.kt index 3c963a0bf5..558ae8454d 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceEvents.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceEvents.kt @@ -10,6 +10,7 @@ package io.element.android.features.space.impl.leave import io.element.android.libraries.matrix.api.core.RoomId sealed interface LeaveSpaceEvents { + data object Retry : LeaveSpaceEvents data object SelectAllRooms : LeaveSpaceEvents data object DeselectAllRooms : LeaveSpaceEvents data class ToggleRoomSelection(val roomId: RoomId) : LeaveSpaceEvents diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt index 2754364676..ffaca68a67 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt @@ -8,10 +8,11 @@ package io.element.android.features.space.impl.leave import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue @@ -26,10 +27,9 @@ import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom -import kotlinx.collections.immutable.ImmutableSet +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableList -import kotlinx.collections.immutable.toPersistentSet import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -42,43 +42,55 @@ class LeaveSpacePresenter( fun create(leaveSpaceHandle: LeaveSpaceHandle): LeaveSpacePresenter } + data class LeaveSpaceRooms( + val current: LeaveSpaceRoom?, + val others: List, + ) + @Composable override fun present(): LeaveSpaceState { val coroutineScope = rememberCoroutineScope() - var currentSpace: LeaveSpaceRoom? by remember { mutableStateOf(null) } + var retryCount by remember { mutableIntStateOf(0) } val leaveSpaceAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } - val selectedRoomIds = remember { - mutableStateOf>(persistentSetOf()) + var selectedRoomIds by remember { + mutableStateOf>(setOf()) } - val leaveSpaceRooms by produceState(AsyncData.Loading()) { + var leaveSpaceRooms by remember { + mutableStateOf>(AsyncData.Loading()) + } + LaunchedEffect(retryCount) { val rooms = leaveSpaceHandle.rooms() val (currentRoom, otherRooms) = rooms.getOrNull() .orEmpty() .partition { it.spaceRoom.roomId == leaveSpaceHandle.id } - currentSpace = currentRoom.firstOrNull() // By default select all rooms that can be left - selectedRoomIds.value = otherRooms + selectedRoomIds = otherRooms .filter { it.isLastAdmin.not() } .map { it.spaceRoom.roomId } - .toPersistentSet() - value = rooms.fold( - onSuccess = { AsyncData.Success(otherRooms) }, + leaveSpaceRooms = rooms.fold( + onSuccess = { + AsyncData.Success( + LeaveSpaceRooms( + current = currentRoom.firstOrNull(), + others = otherRooms.toImmutableList(), + ) + ) + }, onFailure = { AsyncData.Failure(it) } ) } - val selectableSpaceRooms by produceState( - initialValue = AsyncData.Loading(), - key1 = leaveSpaceRooms, - key2 = selectedRoomIds.value, - ) { - value = leaveSpaceRooms.map { list -> - list.orEmpty().map { room -> + var selectableSpaceRooms by remember { + mutableStateOf>>(AsyncData.Loading()) + } + LaunchedEffect(selectedRoomIds, leaveSpaceRooms) { + selectableSpaceRooms = leaveSpaceRooms.map { + it?.others.orEmpty().map { room -> SelectableSpaceRoom( spaceRoom = room.spaceRoom, isLastAdmin = room.isLastAdmin, - isSelected = selectedRoomIds.value.contains(room.spaceRoom.roomId), + isSelected = selectedRoomIds.contains(room.spaceRoom.roomId), ) }.toImmutableList() } @@ -86,28 +98,29 @@ class LeaveSpacePresenter( fun handleEvents(event: LeaveSpaceEvents) { when (event) { + LeaveSpaceEvents.Retry -> { + leaveSpaceRooms = AsyncData.Loading() + retryCount += 1 + } LeaveSpaceEvents.DeselectAllRooms -> { - selectedRoomIds.value = persistentSetOf() + selectedRoomIds = persistentSetOf() } LeaveSpaceEvents.SelectAllRooms -> { - selectedRoomIds.value = selectableSpaceRooms.dataOrNull() + selectedRoomIds = selectableSpaceRooms.dataOrNull() .orEmpty() .filter { it.isLastAdmin.not() } .map { it.spaceRoom.roomId } - .toPersistentSet() } is LeaveSpaceEvents.ToggleRoomSelection -> { - val currentSet = selectedRoomIds.value - selectedRoomIds.value = if (currentSet.contains(event.roomId)) { - currentSet - event.roomId + selectedRoomIds = if (selectedRoomIds.contains(event.roomId)) { + selectedRoomIds - event.roomId } else { - currentSet + event.roomId + selectedRoomIds + event.roomId } - .toPersistentSet() } LeaveSpaceEvents.LeaveSpace -> coroutineScope.leaveSpace( leaveSpaceAction = leaveSpaceAction, - selectedRoomIds = selectedRoomIds.value, + selectedRoomIds = selectedRoomIds, ) LeaveSpaceEvents.CloseError -> { leaveSpaceAction.value = AsyncAction.Uninitialized @@ -116,8 +129,8 @@ class LeaveSpacePresenter( } return LeaveSpaceState( - spaceName = currentSpace?.spaceRoom?.name, - isLastAdmin = currentSpace?.isLastAdmin == true, + spaceName = leaveSpaceRooms.dataOrNull()?.current?.spaceRoom?.name, + isLastAdmin = leaveSpaceRooms.dataOrNull()?.current?.isLastAdmin == true, selectableSpaceRooms = selectableSpaceRooms, leaveSpaceAction = leaveSpaceAction.value, eventSink = ::handleEvents, @@ -126,7 +139,7 @@ class LeaveSpacePresenter( private fun CoroutineScope.leaveSpace( leaveSpaceAction: MutableState>, - selectedRoomIds: Set, + selectedRoomIds: Collection, ) = launch { runUpdatingState(leaveSpaceAction) { leaveSpaceHandle.leave(selectedRoomIds.toList()) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt index c28b1661c7..ebf4bd178a 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt @@ -111,7 +111,9 @@ fun LeaveSpaceView( is AsyncData.Failure -> item { AsyncFailure( throwable = state.selectableSpaceRooms.error, - onRetry = null, + onRetry = { + state.eventSink(LeaveSpaceEvents.Retry) + }, ) } is AsyncData.Loading, diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt index b5d6f90923..5bdd100c93 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt @@ -60,9 +60,15 @@ class LeaveSpacePresenterTest { val state = awaitItem() assertThat(state.selectableSpaceRooms.isLoading()).isTrue() assertThat(state.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) - skipItems(2) + skipItems(3) val stateError = awaitItem() assertThat(stateError.selectableSpaceRooms.isFailure()).isTrue() + // Retry + stateError.eventSink(LeaveSpaceEvents.Retry) + skipItems(1) + val stateLoadingAgain = awaitItem() + assertThat(stateLoadingAgain.selectableSpaceRooms.isLoading()).isTrue() + cancelAndIgnoreRemainingEvents() } } @@ -166,7 +172,7 @@ class LeaveSpacePresenterTest { ) ) presenter.test { - skipItems(3) + skipItems(4) val state = awaitItem() state.eventSink(LeaveSpaceEvents.LeaveSpace) val stateLeaving = awaitItem() From 8d6a75e6627ba13280e90789cc1361717ae977f4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 15:07:41 +0200 Subject: [PATCH 27/73] Use semantics colors. --- .../designsystem/atomic/atoms/BetaLabel.kt | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt index 7ef5b5dec5..12a1dd1c80 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt @@ -14,48 +14,31 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.element.android.compound.annotations.CoreColorToken import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.internal.DarkColorTokens -import io.element.android.compound.tokens.generated.internal.LightColorTokens import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text -@OptIn(CoreColorToken::class) @Composable fun BetaLabel( modifier: Modifier = Modifier, ) { - val (backgroundColor, borderColor, textColor) = if (ElementTheme.isLightTheme) { - listOf( - LightColorTokens.colorGreen300, - LightColorTokens.colorGreen700, - LightColorTokens.colorGreen900, - ) - } else { - listOf( - DarkColorTokens.colorGreen300, - DarkColorTokens.colorGreen700, - DarkColorTokens.colorGreen900, - ) - } val shape = RoundedCornerShape(size = 6.dp) Text( modifier = modifier .border( width = 1.dp, - color = borderColor, + color = ElementTheme.colors.borderInfoSubtle, shape = shape, ) .background( - color = backgroundColor, + color = ElementTheme.colors.bgInfoSubtle, shape = shape, ) .padding(horizontal = 8.dp, vertical = 4.dp), text = "BETA", style = ElementTheme.typography.fontBodySmMedium, - color = textColor, + color = ElementTheme.colors.textInfoPrimary, ) } From 3af56b64a5769fca0211afc698eabb0c1d39939b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 15:11:55 +0200 Subject: [PATCH 28/73] Space announcement: iterate on wording. --- .../impl/spaces/SpaceAnnouncementPresenter.kt | 4 ---- .../impl/spaces/SpaceAnnouncementState.kt | 2 -- .../spaces/SpaceAnnouncementStateProvider.kt | 4 ---- .../impl/spaces/SpaceAnnouncementView.kt | 16 +++++----------- .../impl/src/main/res/values/localazy.xml | 10 +++++----- .../spaces/SpaceAnnouncementPresenterTest.kt | 19 ------------------- 6 files changed, 10 insertions(+), 45 deletions(-) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt index dbe619a867..05c42b784e 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt @@ -13,12 +13,10 @@ import dev.zacsweers.metro.Inject import io.element.android.features.announcement.impl.store.AnnouncementStore import io.element.android.features.announcement.impl.store.AnnouncementStore.SpaceAnnouncement import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.core.meta.BuildMeta import kotlinx.coroutines.launch @Inject class SpaceAnnouncementPresenter( - private val buildMeta: BuildMeta, private val announcementStore: AnnouncementStore, ) : Presenter { @Composable @@ -34,8 +32,6 @@ class SpaceAnnouncementPresenter( } return SpaceAnnouncementState( - applicationName = buildMeta.applicationName, - desktopApplicationName = buildMeta.desktopApplicationName, eventSink = ::handleEvents ) } diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt index f02519a405..7628ed27ae 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt @@ -8,7 +8,5 @@ package io.element.android.features.announcement.impl.spaces data class SpaceAnnouncementState( - val applicationName: String, - val desktopApplicationName: String, val eventSink: (SpaceAnnouncementEvents) -> Unit ) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt index 0eb2e8ff48..d994edf3d8 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt @@ -17,11 +17,7 @@ open class SpaceAnnouncementStateProvider : PreviewParameterProvider Unit = {}, ) = SpaceAnnouncementState( - applicationName = applicationName, - desktopApplicationName = desktopApplicationName, eventSink = eventSink, ) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt index 7f0a7291a5..2a8c5257aa 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt @@ -55,11 +55,10 @@ fun SpaceAnnouncementView( isScrollable = true, contentPadding = PaddingValues(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 24.dp), header = { - SpaceAnnouncementHeader(state = state) + SpaceAnnouncementHeader() }, content = { SpaceAnnouncementContent( - state = state, modifier = Modifier.padding(horizontal = 8.dp), ) }, @@ -73,17 +72,13 @@ fun SpaceAnnouncementView( @Composable private fun SpaceAnnouncementHeader( - state: SpaceAnnouncementState, modifier: Modifier = Modifier, ) { IconTitleSubtitleMolecule( modifier = modifier.padding(top = 16.dp, bottom = 16.dp), title = stringResource(id = R.string.screen_space_announcement_title), showBetaLabel = true, - subTitle = stringResource( - id = R.string.screen_space_announcement_subtitle, - state.applicationName - ), + subTitle = stringResource(id = R.string.screen_space_announcement_subtitle), iconStyle = BigIcon.Style.Default( vectorIcon = CompoundIcons.WorkspaceSolid(), usePrimaryTint = true, @@ -93,7 +88,6 @@ private fun SpaceAnnouncementHeader( @Composable private fun SpaceAnnouncementContent( - state: SpaceAnnouncementState, modifier: Modifier = Modifier, ) { Column( @@ -103,7 +97,7 @@ private fun SpaceAnnouncementContent( modifier = Modifier.fillMaxWidth(), items = persistentListOf( InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item1, state.desktopApplicationName), + message = stringResource(id = R.string.screen_space_announcement_item1), iconVector = CompoundIcons.VisibilityOn(), ), InfoListItem( @@ -116,11 +110,11 @@ private fun SpaceAnnouncementContent( ), InfoListItem( message = stringResource(id = R.string.screen_space_announcement_item4), - iconVector = CompoundIcons.Leave(), + iconVector = CompoundIcons.Explore(), ), InfoListItem( message = stringResource(id = R.string.screen_space_announcement_item5), - iconVector = CompoundIcons.Explore(), + iconVector = CompoundIcons.Leave(), ), ), textStyle = ElementTheme.typography.fontBodyLgMedium, diff --git a/features/announcement/impl/src/main/res/values/localazy.xml b/features/announcement/impl/src/main/res/values/localazy.xml index b995021dfd..eff394be10 100644 --- a/features/announcement/impl/src/main/res/values/localazy.xml +++ b/features/announcement/impl/src/main/res/values/localazy.xml @@ -1,11 +1,11 @@ - "View spaces you’ve created or joined on %1$s desktop" + "View spaces you\'ve created or joined" "Accept or decline invites to spaces" "Discover any rooms you can join in your spaces" - "Leave any spaces you’ve joined" - "Join public spaces" - "More features will be added in the future, such as creating or managing spaces on mobile." - "Welcome to the beta version of Spaces on %1$s mobile! With this first version you can:" + "Join public spaces" + "Leave any spaces you’ve joined" + "Creating and managing spaces is coming soon." + "Welcome to the beta version of Spaces! With this first version you can:" "Introducing Spaces" diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt index c3ab3a410c..5adb4dccec 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt @@ -10,26 +10,12 @@ package io.element.android.features.announcement.impl.spaces import com.google.common.truth.Truth.assertThat import io.element.android.features.announcement.impl.store.AnnouncementStore import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore -import io.element.android.libraries.core.meta.BuildMeta -import io.element.android.libraries.matrix.test.AN_APPLICATION_NAME -import io.element.android.libraries.matrix.test.AN_APPLICATION_NAME_DESKTOP -import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Test class SpaceAnnouncementPresenterTest { - @Test - fun `present - initial state`() = runTest { - val presenter = createSpaceAnnouncementPresenter() - presenter.test { - val state = awaitItem() - assertThat(state.applicationName).isEqualTo(AN_APPLICATION_NAME) - assertThat(state.desktopApplicationName).isEqualTo(AN_APPLICATION_NAME_DESKTOP) - } - } - @Test fun `present - when user continues, the store is updated`() = runTest { val store = InMemoryAnnouncementStore() @@ -46,12 +32,7 @@ class SpaceAnnouncementPresenterTest { } private fun createSpaceAnnouncementPresenter( - buildMeta: BuildMeta = aBuildMeta( - applicationName = AN_APPLICATION_NAME, - desktopApplicationName = AN_APPLICATION_NAME_DESKTOP, - ), announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), ) = SpaceAnnouncementPresenter( - buildMeta = buildMeta, announcementStore = announcementStore, ) From 3ff3079ba7088e2ca6e3935a7a85d228883974ce Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 3 Oct 2025 13:13:53 +0000 Subject: [PATCH 29/73] Update screenshots --- .../features.space.impl.leave_LeaveSpaceView_Day_8_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_8_en.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png index 5040a8439e..58c84eca38 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:792f623cbd264f29724864f2d8db1c8044580fe309241b0a9afd8bea355ba289 -size 13862 +oid sha256:6d5be43f0ae09dfea01efa28519b003c6c3bbd8a47c8329ccc9721acdc84a116 +size 16531 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png index 76f1c87fd1..501d938326 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fffb92c5520c5b8665ce4be8eba4f1d9133047140ef116562440a40f319dc2ac -size 13852 +oid sha256:16d9c0ce7ffefb7825efb5e824c06bc721f85f3ff88340abf9c41b2b4679492c +size 16435 From cfe7d94450d57379b58d423cfcdc673ebde485b8 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 3 Oct 2025 13:27:43 +0000 Subject: [PATCH 30/73] Update screenshots --- ...nnouncement.impl.spaces_SpaceAnnouncementView_Day_0_en.png | 4 ++-- ...ouncement.impl.spaces_SpaceAnnouncementView_Night_0_en.png | 4 ++-- ...libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png | 4 ++-- ...braries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png index d162a35968..e74a44bc85 100644 --- a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbaf478329e93e8762e5063e984ca124ab15171950a354324d353cd8454d2d9d -size 65293 +oid sha256:780559f9a0677b007c93f0c24bef94ab63c89f2d8c124084557c5c8dec0ea3d6 +size 60500 diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png index fef29ced8c..3634085549 100644 --- a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:036f5e862232821552b7a7a25d32de3d65b7de68a4c410231bcf300b8952d6dc -size 64055 +oid sha256:97e068729df68971b35727236873cc7954ae5e63890f255948fb4ccd98b3ae2f +size 59572 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png index 5b11b1434d..9957d3f2a8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63de7652fe0a3f62ba1cbb00d3a5cb49e620552d8ebb07b9cab916c5ca810538 -size 5175 +oid sha256:e6453b165bca4b509d7a2e1749e0534f5f12465de3b32bb0513cf377021a57a5 +size 5080 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png index 2041b72844..abea5053c1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d71a95f7319fb5c73a456eeae3a0c8bd67c489c460620ad76516f33ca6de364 -size 4972 +oid sha256:2431e2c666af3353ae85d9a101d8dde1378b4fa3d1828ff23a7f4753f6fb2725 +size 5112 From 729959026d50d954d8780493bf9f1f0ef8cfbede Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 16:11:25 +0200 Subject: [PATCH 31/73] Fix lint issue by removing old translations --- features/space/impl/src/main/res/values-cs/translations.xml | 1 - features/space/impl/src/main/res/values-da/translations.xml | 1 - features/space/impl/src/main/res/values-de/translations.xml | 1 - features/space/impl/src/main/res/values-fr/translations.xml | 1 - features/space/impl/src/main/res/values-hu/translations.xml | 1 - 5 files changed, 5 deletions(-) diff --git a/features/space/impl/src/main/res/values-cs/translations.xml b/features/space/impl/src/main/res/values-cs/translations.xml index 8a0886e786..8ab1f64989 100644 --- a/features/space/impl/src/main/res/values-cs/translations.xml +++ b/features/space/impl/src/main/res/values-cs/translations.xml @@ -1,6 +1,5 @@ - "(Správce)" "Opustit %1$d místnost a prostor" "Opustit %1$d místnosti a prostor" diff --git a/features/space/impl/src/main/res/values-da/translations.xml b/features/space/impl/src/main/res/values-da/translations.xml index ee6c2fcfb9..4863ff7cca 100644 --- a/features/space/impl/src/main/res/values-da/translations.xml +++ b/features/space/impl/src/main/res/values-da/translations.xml @@ -1,6 +1,5 @@ - "Administrator" "Forlad %1$d rum og klynge" "Forlad %1$d rum og klynger" diff --git a/features/space/impl/src/main/res/values-de/translations.xml b/features/space/impl/src/main/res/values-de/translations.xml index faab578205..2ecdac3115 100644 --- a/features/space/impl/src/main/res/values-de/translations.xml +++ b/features/space/impl/src/main/res/values-de/translations.xml @@ -1,6 +1,5 @@ - "(Admin)" "%1$d Chat und Space verlassen" "%1$d Chats und Space verlassen" diff --git a/features/space/impl/src/main/res/values-fr/translations.xml b/features/space/impl/src/main/res/values-fr/translations.xml index 5ff48f6c39..3c9f2d3ab9 100644 --- a/features/space/impl/src/main/res/values-fr/translations.xml +++ b/features/space/impl/src/main/res/values-fr/translations.xml @@ -1,6 +1,5 @@ - "(Admin)" "Quitter %1$d salon et l’espace" "Quitter %1$d salons et l’espace" diff --git a/features/space/impl/src/main/res/values-hu/translations.xml b/features/space/impl/src/main/res/values-hu/translations.xml index 8196780cf9..bb326f759a 100644 --- a/features/space/impl/src/main/res/values-hu/translations.xml +++ b/features/space/impl/src/main/res/values-hu/translations.xml @@ -1,6 +1,5 @@ - "(Adminisztrátor)" "%1$d szoba és tér elhagyása" "%1$d szoba és tér elhagyása" From d2dfc0424874da35c84fba3882d179751201a6cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:49:43 +0200 Subject: [PATCH 32/73] chore(deps): update gradle/actions action to v5 (#5444) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/build_enterprise.yml | 2 +- .github/workflows/generate_github_pages.yml | 2 +- .github/workflows/maestro-local.yml | 2 +- .github/workflows/nightlyReports.yml | 4 ++-- .github/workflows/quality.yml | 12 ++++++------ .github/workflows/recordScreenshots.yml | 2 +- .github/workflows/release.yml | 6 +++--- .github/workflows/sonar.yml | 2 +- .github/workflows/sync-localazy.yml | 2 +- .github/workflows/tests.yml | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eaea9a841d..fb14c3cee6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Assemble debug APKs diff --git a/.github/workflows/build_enterprise.yml b/.github/workflows/build_enterprise.yml index 9c4c8cec8f..0d9b5949cc 100644 --- a/.github/workflows/build_enterprise.yml +++ b/.github/workflows/build_enterprise.yml @@ -44,7 +44,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Assemble debug Gplay Enterprise APK diff --git a/.github/workflows/generate_github_pages.yml b/.github/workflows/generate_github_pages.yml index a4286491cb..0d03d1a928 100644 --- a/.github/workflows/generate_github_pages.yml +++ b/.github/workflows/generate_github_pages.yml @@ -19,7 +19,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Set up Python 3.12 diff --git a/.github/workflows/maestro-local.yml b/.github/workflows/maestro-local.yml index 64eff695d9..7481bec0ba 100644 --- a/.github/workflows/maestro-local.yml +++ b/.github/workflows/maestro-local.yml @@ -34,7 +34,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Assemble debug APK diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index f89373b44f..537565743e 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -27,7 +27,7 @@ jobs: java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: false @@ -67,7 +67,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Dependency analysis diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 6e9dea69ab..773bc02d93 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -52,7 +52,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Set up Python 3.12 @@ -90,7 +90,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Run Konsist tests @@ -130,7 +130,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Build Gplay Debug @@ -174,7 +174,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Run Detekt @@ -214,7 +214,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Run Ktlint check @@ -254,7 +254,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Run Knit diff --git a/.github/workflows/recordScreenshots.yml b/.github/workflows/recordScreenshots.yml index a4d54afeb4..bbcbef04d8 100644 --- a/.github/workflows/recordScreenshots.yml +++ b/.github/workflows/recordScreenshots.yml @@ -40,7 +40,7 @@ jobs: java-version: '21' # Add gradle cache, this should speed up the process - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Record screenshots diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 661110338d..2cce85bd5a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 - name: Create app bundle env: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} @@ -66,7 +66,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 - name: Create Enterprise app bundle env: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} @@ -94,7 +94,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 - name: Create APKs env: ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }} diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 080fcef0e0..acfe6ba87f 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -33,7 +33,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Build debug code and test fixtures diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index b5548fd2b1..7740af4064 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -18,7 +18,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} - name: Set up Python 3.12 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 55f27aa9ba..c0249642f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,7 +52,7 @@ jobs: distribution: 'temurin' # See 'Supported distributions' for available options java-version: '21' - name: Configure gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@v5 with: cache-read-only: ${{ github.ref != 'refs/heads/develop' }} From 4de1388673c75d60cb13b11cf0dc56efb010892e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:53:03 +0200 Subject: [PATCH 33/73] fix(deps): update dependency io.sentry:sentry-android to v8.23.0 (#5442) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ddb57658ce..89c634a7ce 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -206,7 +206,7 @@ haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = # Analytics posthog = "com.posthog:posthog-android:3.22.0" -sentry = "io.sentry:sentry-android:8.22.0" +sentry = "io.sentry:sentry-android:8.23.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.28.0" From 4660e99d11b2abd7bf901fbab5116749dcc31fba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 15:14:51 +0000 Subject: [PATCH 34/73] Update dependency org.maplibre.gl:android-sdk to v12 (#5455) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 89c634a7ce..d9990bbbf9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -196,7 +196,7 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:11.13.5" +maplibre = "org.maplibre.gl:android-sdk:12.0.0" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" From bfbabd84c32b4b97029981f4f8b3642ece4687b3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 3 Oct 2025 18:19:25 +0200 Subject: [PATCH 35/73] feature(space) : keep space children in the presenter --- .../android/features/space/impl/root/SpacePresenter.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index 7a3481bb73..fdd090066e 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.features.invite.api.SeenInvitesStore @@ -32,6 +33,7 @@ import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentMap @@ -50,18 +52,22 @@ class SpacePresenter( private val acceptDeclineInvitePresenter: Presenter, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, ) : Presenter { + private var children by mutableStateOf(persistentListOf()) + @Composable override fun present(): SpaceState { LaunchedEffect(Unit) { paginate() + spaceRoomList.spaceRoomsFlow.collect { children = it.toPersistentList() } } + val hideInvitesAvatar by client.rememberHideInvitesAvatar() val seenSpaceInvites by remember { seenInvitesStore.seenRoomIds().map { it.toPersistentSet() } }.collectAsState(persistentSetOf()) val localCoroutineScope = rememberCoroutineScope() - val children by spaceRoomList.spaceRoomsFlow.collectAsState(emptyList()) + val hasMoreToLoad by remember { spaceRoomList.paginationStatusFlow.mapState { status -> when (status) { @@ -110,7 +116,7 @@ class SpacePresenter( } return SpaceState( currentSpace = currentSpace.getOrNull(), - children = children.toPersistentList(), + children = children, seenSpaceInvites = seenSpaceInvites, hideInvitesAvatar = hideInvitesAvatar, hasMoreToLoad = hasMoreToLoad, From 95f1dc9bae6b343809c099f5730c8a418f6ab7dd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:23:27 +0200 Subject: [PATCH 36/73] Import Compound code from project https://github.com/element-hq/compound-android --- features/enterprise/api/build.gradle.kts | 2 +- .../enterprise/impl-foss/build.gradle.kts | 2 +- features/enterprise/test/build.gradle.kts | 2 +- gradle/libs.versions.toml | 1 - libraries/compound/build.gradle.kts | 25 + .../compound/annotations/CoreColorToken.kt | 13 + .../compound/previews/ColorListPreview.kt | 57 + .../android/compound/previews/ColorPreview.kt | 62 + .../compound/previews/ColorsSchemePreview.kt | 60 + .../compound/previews/CompoundIconsPreview.kt | 141 +++ .../previews/SemanticColorsPreview.kt | 205 ++++ .../android/compound/previews/Typography.kt | 49 + .../showkase/CompoundShowkaseRootModule.kt | 14 + .../android/compound/theme/AvatarColors.kt | 91 ++ .../android/compound/theme/ElementTheme.kt | 165 +++ .../compound/theme/ForcedDarkElementTheme.kt | 51 + .../android/compound/theme/LegacyColors.kt | 27 + .../compound/theme/MaterialColorSchemeDark.kt | 52 + .../theme/MaterialColorSchemeLight.kt | 52 + .../compound/theme/MaterialTextPreview.kt | 139 +++ .../compound/theme/MaterialThemeColors.kt | 72 ++ .../element/android/compound/theme/Theme.kt | 37 + .../compound/tokens/CompoundTypography.kt | 93 ++ .../tokens/generated/CompoundIcons.kt | 1034 +++++++++++++++++ .../tokens/generated/DO_NOT_MODIFY.txt | 1 + .../tokens/generated/SemanticColors.kt | 222 ++++ .../tokens/generated/SemanticColorsDark.kt | 121 ++ .../tokens/generated/SemanticColorsDarkHc.kt | 121 ++ .../tokens/generated/SemanticColorsLight.kt | 121 ++ .../tokens/generated/SemanticColorsLightHc.kt | 121 ++ .../tokens/generated/TypographyTokens.kt | 174 +++ .../generated/internal/DarkColorTokens.kt | 335 ++++++ .../generated/internal/DarkHcColorTokens.kt | 335 ++++++ .../generated/internal/LightColorTokens.kt | 335 ++++++ .../generated/internal/LightHcColorTokens.kt | 335 ++++++ .../android/compound/utils/ColorUtils.kt | 17 + .../main/res/drawable/ic_compound_admin.xml | 10 + .../res/drawable/ic_compound_arrow_down.xml | 9 + .../res/drawable/ic_compound_arrow_left.xml | 10 + .../res/drawable/ic_compound_arrow_right.xml | 10 + .../res/drawable/ic_compound_arrow_up.xml | 9 + .../drawable/ic_compound_arrow_up_right.xml | 10 + .../res/drawable/ic_compound_ask_to_join.xml | 9 + .../ic_compound_ask_to_join_solid.xml | 9 + .../res/drawable/ic_compound_attachment.xml | 10 + .../main/res/drawable/ic_compound_audio.xml | 9 + .../main/res/drawable/ic_compound_block.xml | 10 + .../main/res/drawable/ic_compound_bold.xml | 9 + .../res/drawable/ic_compound_calendar.xml | 9 + .../main/res/drawable/ic_compound_chart.xml | 10 + .../main/res/drawable/ic_compound_chat.xml | 10 + .../res/drawable/ic_compound_chat_new.xml | 13 + .../res/drawable/ic_compound_chat_problem.xml | 13 + .../res/drawable/ic_compound_chat_solid.xml | 10 + .../main/res/drawable/ic_compound_check.xml | 9 + .../res/drawable/ic_compound_check_circle.xml | 9 + .../ic_compound_check_circle_solid.xml | 9 + .../res/drawable/ic_compound_chevron_down.xml | 9 + .../res/drawable/ic_compound_chevron_left.xml | 10 + .../drawable/ic_compound_chevron_right.xml | 10 + .../res/drawable/ic_compound_chevron_up.xml | 9 + .../drawable/ic_compound_chevron_up_down.xml | 9 + .../main/res/drawable/ic_compound_circle.xml | 9 + .../main/res/drawable/ic_compound_close.xml | 9 + .../main/res/drawable/ic_compound_cloud.xml | 10 + .../res/drawable/ic_compound_cloud_solid.xml | 10 + .../main/res/drawable/ic_compound_code.xml | 9 + .../res/drawable/ic_compound_collapse.xml | 10 + .../main/res/drawable/ic_compound_company.xml | 10 + .../main/res/drawable/ic_compound_compose.xml | 14 + .../res/drawable/ic_compound_computer.xml | 9 + .../main/res/drawable/ic_compound_copy.xml | 13 + .../res/drawable/ic_compound_dark_mode.xml | 11 + .../main/res/drawable/ic_compound_delete.xml | 9 + .../main/res/drawable/ic_compound_devices.xml | 10 + .../res/drawable/ic_compound_dial_pad.xml | 9 + .../res/drawable/ic_compound_document.xml | 10 + .../res/drawable/ic_compound_download.xml | 9 + .../res/drawable/ic_compound_download_ios.xml | 12 + .../res/drawable/ic_compound_drag_grid.xml | 9 + .../res/drawable/ic_compound_drag_list.xml | 9 + .../res/drawable/ic_compound_earpiece.xml | 13 + .../main/res/drawable/ic_compound_edit.xml | 11 + .../res/drawable/ic_compound_edit_solid.xml | 11 + .../main/res/drawable/ic_compound_email.xml | 9 + .../res/drawable/ic_compound_email_solid.xml | 9 + .../res/drawable/ic_compound_end_call.xml | 9 + .../main/res/drawable/ic_compound_error.xml | 9 + .../res/drawable/ic_compound_error_solid.xml | 9 + .../main/res/drawable/ic_compound_expand.xml | 10 + .../main/res/drawable/ic_compound_explore.xml | 9 + .../drawable/ic_compound_export_archive.xml | 9 + .../res/drawable/ic_compound_extensions.xml | 10 + .../drawable/ic_compound_extensions_solid.xml | 10 + .../res/drawable/ic_compound_favourite.xml | 9 + .../drawable/ic_compound_favourite_solid.xml | 9 + .../res/drawable/ic_compound_file_error.xml | 13 + .../main/res/drawable/ic_compound_files.xml | 10 + .../main/res/drawable/ic_compound_filter.xml | 9 + .../main/res/drawable/ic_compound_forward.xml | 10 + .../main/res/drawable/ic_compound_grid.xml | 9 + .../main/res/drawable/ic_compound_group.xml | 9 + .../main/res/drawable/ic_compound_guest.xml | 13 + .../ic_compound_headphones_off_solid.xml | 9 + .../drawable/ic_compound_headphones_solid.xml | 9 + .../main/res/drawable/ic_compound_help.xml | 12 + .../res/drawable/ic_compound_help_solid.xml | 9 + .../main/res/drawable/ic_compound_history.xml | 13 + .../main/res/drawable/ic_compound_home.xml | 10 + .../res/drawable/ic_compound_home_solid.xml | 9 + .../main/res/drawable/ic_compound_host.xml | 14 + .../main/res/drawable/ic_compound_image.xml | 13 + .../res/drawable/ic_compound_image_error.xml | 13 + .../drawable/ic_compound_indent_decrease.xml | 10 + .../drawable/ic_compound_indent_increase.xml | 10 + .../main/res/drawable/ic_compound_info.xml | 13 + .../res/drawable/ic_compound_info_solid.xml | 9 + .../res/drawable/ic_compound_inline_code.xml | 9 + .../main/res/drawable/ic_compound_italic.xml | 10 + .../src/main/res/drawable/ic_compound_key.xml | 10 + .../main/res/drawable/ic_compound_key_off.xml | 13 + .../drawable/ic_compound_key_off_solid.xml | 10 + .../res/drawable/ic_compound_key_solid.xml | 10 + .../res/drawable/ic_compound_keyboard.xml | 13 + .../main/res/drawable/ic_compound_labs.xml | 16 + .../main/res/drawable/ic_compound_leave.xml | 13 + .../main/res/drawable/ic_compound_link.xml | 10 + .../main/res/drawable/ic_compound_linux.xml | 17 + .../drawable/ic_compound_list_bulleted.xml | 10 + .../drawable/ic_compound_list_numbered.xml | 9 + .../res/drawable/ic_compound_list_view.xml | 16 + .../ic_compound_location_navigator.xml | 9 + ...ic_compound_location_navigator_centred.xml | 9 + .../res/drawable/ic_compound_location_pin.xml | 9 + .../ic_compound_location_pin_solid.xml | 9 + .../main/res/drawable/ic_compound_lock.xml | 9 + .../res/drawable/ic_compound_lock_off.xml | 10 + .../res/drawable/ic_compound_lock_solid.xml | 9 + .../src/main/res/drawable/ic_compound_mac.xml | 10 + .../res/drawable/ic_compound_mark_as_read.xml | 9 + .../drawable/ic_compound_mark_as_unread.xml | 14 + .../ic_compound_mark_threads_as_read.xml | 10 + .../ic_compound_marker_read_receipts.xml | 13 + .../main/res/drawable/ic_compound_mention.xml | 9 + .../main/res/drawable/ic_compound_menu.xml | 9 + .../main/res/drawable/ic_compound_mic_off.xml | 14 + .../drawable/ic_compound_mic_off_solid.xml | 10 + .../main/res/drawable/ic_compound_mic_on.xml | 13 + .../res/drawable/ic_compound_mic_on_solid.xml | 12 + .../main/res/drawable/ic_compound_minus.xml | 9 + .../main/res/drawable/ic_compound_mobile.xml | 9 + .../drawable/ic_compound_notifications.xml | 9 + .../ic_compound_notifications_off.xml | 13 + .../ic_compound_notifications_off_solid.xml | 13 + .../ic_compound_notifications_solid.xml | 9 + .../main/res/drawable/ic_compound_offline.xml | 10 + .../ic_compound_overflow_horizontal.xml | 9 + .../ic_compound_overflow_vertical.xml | 9 + .../main/res/drawable/ic_compound_pause.xml | 9 + .../res/drawable/ic_compound_pause_solid.xml | 9 + .../src/main/res/drawable/ic_compound_pin.xml | 10 + .../res/drawable/ic_compound_pin_solid.xml | 9 + .../main/res/drawable/ic_compound_play.xml | 10 + .../res/drawable/ic_compound_play_solid.xml | 10 + .../main/res/drawable/ic_compound_plus.xml | 9 + .../main/res/drawable/ic_compound_polls.xml | 10 + .../res/drawable/ic_compound_polls_end.xml | 13 + .../main/res/drawable/ic_compound_pop_out.xml | 13 + .../res/drawable/ic_compound_preferences.xml | 10 + .../ic_compound_presence_outline_8_x_8.xml | 12 + .../ic_compound_presence_solid_8_x_8.xml | 11 + ..._compound_presence_strikethrough_8_x_8.xml | 12 + .../main/res/drawable/ic_compound_public.xml | 9 + .../main/res/drawable/ic_compound_qr_code.xml | 17 + .../main/res/drawable/ic_compound_quote.xml | 10 + .../ic_compound_raised_hand_solid.xml | 9 + .../res/drawable/ic_compound_reaction.xml | 12 + .../res/drawable/ic_compound_reaction_add.xml | 13 + .../drawable/ic_compound_reaction_solid.xml | 10 + .../main/res/drawable/ic_compound_reply.xml | 10 + .../main/res/drawable/ic_compound_restart.xml | 10 + .../main/res/drawable/ic_compound_room.xml | 10 + .../main/res/drawable/ic_compound_search.xml | 10 + .../main/res/drawable/ic_compound_send.xml | 11 + .../res/drawable/ic_compound_send_solid.xml | 10 + .../res/drawable/ic_compound_settings.xml | 12 + .../drawable/ic_compound_settings_solid.xml | 9 + .../main/res/drawable/ic_compound_share.xml | 9 + .../drawable/ic_compound_share_android.xml | 10 + .../res/drawable/ic_compound_share_ios.xml | 12 + .../res/drawable/ic_compound_share_screen.xml | 12 + .../ic_compound_share_screen_solid.xml | 9 + .../main/res/drawable/ic_compound_shield.xml | 10 + .../main/res/drawable/ic_compound_sidebar.xml | 11 + .../res/drawable/ic_compound_sign_out.xml | 10 + .../main/res/drawable/ic_compound_spinner.xml | 11 + .../res/drawable/ic_compound_spotlight.xml | 10 + .../drawable/ic_compound_spotlight_view.xml | 10 + .../drawable/ic_compound_strikethrough.xml | 9 + .../ic_compound_switch_camera_solid.xml | 13 + .../res/drawable/ic_compound_take_photo.xml | 9 + .../drawable/ic_compound_take_photo_solid.xml | 10 + .../drawable/ic_compound_text_formatting.xml | 9 + .../main/res/drawable/ic_compound_threads.xml | 13 + .../drawable/ic_compound_threads_solid.xml | 10 + .../main/res/drawable/ic_compound_time.xml | 13 + .../res/drawable/ic_compound_underline.xml | 9 + .../main/res/drawable/ic_compound_unknown.xml | 13 + .../drawable/ic_compound_unknown_solid.xml | 10 + .../main/res/drawable/ic_compound_unpin.xml | 14 + .../main/res/drawable/ic_compound_user.xml | 9 + .../res/drawable/ic_compound_user_add.xml | 10 + .../drawable/ic_compound_user_add_solid.xml | 10 + .../res/drawable/ic_compound_user_profile.xml | 15 + .../ic_compound_user_profile_solid.xml | 12 + .../res/drawable/ic_compound_user_solid.xml | 9 + .../res/drawable/ic_compound_verified.xml | 9 + .../res/drawable/ic_compound_video_call.xml | 10 + .../ic_compound_video_call_declined_solid.xml | 10 + .../ic_compound_video_call_missed_solid.xml | 10 + .../drawable/ic_compound_video_call_off.xml | 10 + .../ic_compound_video_call_off_solid.xml | 10 + .../drawable/ic_compound_video_call_solid.xml | 10 + .../drawable/ic_compound_visibility_off.xml | 10 + .../drawable/ic_compound_visibility_on.xml | 9 + .../res/drawable/ic_compound_voice_call.xml | 13 + .../drawable/ic_compound_voice_call_solid.xml | 10 + .../res/drawable/ic_compound_volume_off.xml | 10 + .../drawable/ic_compound_volume_off_solid.xml | 10 + .../res/drawable/ic_compound_volume_on.xml | 13 + .../drawable/ic_compound_volume_on_solid.xml | 13 + .../main/res/drawable/ic_compound_warning.xml | 13 + .../res/drawable/ic_compound_web_browser.xml | 9 + .../main/res/drawable/ic_compound_windows.xml | 9 + .../res/drawable/ic_compound_workspace.xml | 9 + .../drawable/ic_compound_workspace_solid.xml | 9 + libraries/designsystem/build.gradle.kts | 2 +- 237 files changed, 6766 insertions(+), 5 deletions(-) create mode 100644 libraries/compound/build.gradle.kts create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorListPreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorPreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorsSchemePreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/SemanticColorsPreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/showkase/CompoundShowkaseRootModule.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/LegacyColors.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeDark.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeLight.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialThemeColors.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/CompoundTypography.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/CompoundIcons.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/DO_NOT_MODIFY.txt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDark.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDarkHc.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLight.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLightHc.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt create mode 100644 libraries/compound/src/main/kotlin/io/element/android/compound/utils/ColorUtils.kt create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_admin.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_arrow_down.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_arrow_left.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_arrow_right.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_arrow_up.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_arrow_up_right.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_ask_to_join.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_ask_to_join_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_attachment.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_audio.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_block.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_bold.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_calendar.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chart.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chat.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chat_new.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chat_problem.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chat_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_check.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_check_circle.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_check_circle_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chevron_down.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chevron_left.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chevron_right.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chevron_up.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_chevron_up_down.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_circle.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_close.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_cloud.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_cloud_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_code.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_collapse.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_company.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_compose.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_computer.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_copy.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_dark_mode.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_delete.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_devices.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_dial_pad.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_document.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_download.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_download_ios.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_drag_grid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_drag_list.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_earpiece.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_edit.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_edit_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_email.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_email_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_end_call.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_error.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_error_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_expand.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_explore.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_export_archive.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_extensions.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_extensions_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_favourite.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_favourite_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_file_error.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_files.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_filter.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_forward.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_grid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_group.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_guest.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_headphones_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_headphones_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_help.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_help_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_history.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_home.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_home_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_host.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_image.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_image_error.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_indent_decrease.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_indent_increase.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_info.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_info_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_inline_code.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_italic.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_key.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_key_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_key_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_key_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_keyboard.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_labs.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_leave.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_link.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_linux.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_list_bulleted.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_list_numbered.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_list_view.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_location_navigator.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_location_navigator_centred.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_location_pin.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_location_pin_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_lock.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_lock_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_lock_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mac.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mark_as_read.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mark_as_unread.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mark_threads_as_read.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_marker_read_receipts.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mention.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_menu.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mic_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mic_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mic_on.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mic_on_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_minus.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_mobile.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_notifications.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_notifications_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_notifications_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_notifications_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_offline.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_overflow_horizontal.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_overflow_vertical.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_pause.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_pause_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_pin.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_pin_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_play.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_play_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_plus.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_polls.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_polls_end.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_pop_out.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_preferences.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_presence_outline_8_x_8.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_presence_solid_8_x_8.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_presence_strikethrough_8_x_8.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_public.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_qr_code.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_quote.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_raised_hand_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_reaction.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_reaction_add.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_reaction_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_reply.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_restart.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_room.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_search.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_send.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_send_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_settings.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_settings_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_share.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_share_android.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_share_ios.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_share_screen.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_share_screen_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_shield.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_sidebar.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_sign_out.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_spinner.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_spotlight.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_spotlight_view.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_strikethrough.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_switch_camera_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_take_photo.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_take_photo_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_text_formatting.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_threads.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_time.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_underline.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_unknown.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_unknown_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_unpin.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user_add.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user_add_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user_profile.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user_profile_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_user_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_verified.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call_declined_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call_missed_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_video_call_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_visibility_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_visibility_on.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_voice_call.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_voice_call_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_volume_off.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_volume_off_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_volume_on.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_volume_on_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_warning.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_web_browser.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_windows.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_workspace.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml diff --git a/features/enterprise/api/build.gradle.kts b/features/enterprise/api/build.gradle.kts index 9f63ab2cf1..b32f42e31f 100644 --- a/features/enterprise/api/build.gradle.kts +++ b/features/enterprise/api/build.gradle.kts @@ -13,7 +13,7 @@ android { } dependencies { - implementation(libs.compound) + implementation(projects.libraries.compound) implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) } diff --git a/features/enterprise/impl-foss/build.gradle.kts b/features/enterprise/impl-foss/build.gradle.kts index 956c0e1900..c5c194807f 100644 --- a/features/enterprise/impl-foss/build.gradle.kts +++ b/features/enterprise/impl-foss/build.gradle.kts @@ -18,7 +18,7 @@ android { setupDependencyInjection() dependencies { - implementation(libs.compound) + implementation(projects.libraries.compound) api(projects.features.enterprise.api) implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) diff --git a/features/enterprise/test/build.gradle.kts b/features/enterprise/test/build.gradle.kts index 91b76f4fa7..38cc7aaaa9 100644 --- a/features/enterprise/test/build.gradle.kts +++ b/features/enterprise/test/build.gradle.kts @@ -14,7 +14,7 @@ android { dependencies { api(projects.features.enterprise.api) - implementation(libs.compound) + implementation(projects.libraries.compound) implementation(projects.libraries.matrix.api) implementation(projects.tests.testutils) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d9990bbbf9..78b085fd41 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -174,7 +174,6 @@ coil_network_okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version coil_compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } coil_gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" } coil_test = { module = "io.coil-kt.coil3:coil-test", version.ref = "coil" } -compound = { module = "io.element.android:compound-android", version = "25.7.4" } datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" } serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" } kotlinx_collections_immutable = "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.4.0" diff --git a/libraries/compound/build.gradle.kts b/libraries/compound/build.gradle.kts new file mode 100644 index 0000000000..fd99035c65 --- /dev/null +++ b/libraries/compound/build.gradle.kts @@ -0,0 +1,25 @@ +/* + * Copyright 2022, 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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.compound" + + defaultConfig { + vectorDrawables { + useSupportLibrary = true + generatedDensities() + } + } + + dependencies { + implementation(libs.showkase) + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt new file mode 100644 index 0000000000..b80b8653ea --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2023, 2024 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.compound.annotations + +@RequiresOptIn("This is a Core color token, which should only be used to declare semantic colors, otherwise it would look the same on both light and dark modes. Only use it as is if you know what you are doing.") +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) +annotation class CoreColorToken diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorListPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorListPreview.kt new file mode 100644 index 0000000000..715da1ebc3 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorListPreview.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2023, 2024 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.compound.previews + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import kotlinx.collections.immutable.ImmutableMap +import kotlin.math.ceil + +@Composable +fun ColorListPreview( + backgroundColor: Color, + foregroundColor: Color, + colors: ImmutableMap, + modifier: Modifier = Modifier, + numColumns: Int = 1, +) { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + colors.keys + .chunked(ceil(colors.keys.size / numColumns.toDouble()).toInt()) + .forEach { subList -> + Column( + modifier = Modifier + .background(color = backgroundColor) + .weight(1f) + ) { + subList.forEach { name -> + val color = colors[name]!! + ColorPreview( + backgroundColor = backgroundColor, + foregroundColor = foregroundColor, + name = name, + color = color + ) + } + Spacer(modifier = Modifier.height(2.dp)) + } + } + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorPreview.kt new file mode 100644 index 0000000000..3248adeedf --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorPreview.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2023, 2024 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.compound.previews + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.compound.utils.toHrf + +@Composable +fun ColorPreview( + backgroundColor: Color, + foregroundColor: Color, + name: String, + color: Color, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier.fillMaxWidth()) { + Text( + modifier = Modifier.padding(horizontal = 10.dp), + text = name + " " + color.toHrf(), + fontSize = 6.sp, + color = foregroundColor, + ) + val backgroundBrush = Brush.linearGradient( + listOf( + backgroundColor, + foregroundColor, + ) + ) + Row( + modifier = Modifier.background(backgroundBrush) + ) { + repeat(2) { + Box( + modifier = Modifier + .padding(1.dp) + .background(Color.White) + .background(color = color) + .height(10.dp) + .weight(1f) + ) + } + } + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorsSchemePreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorsSchemePreview.kt new file mode 100644 index 0000000000..cf660ba236 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/ColorsSchemePreview.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2023, 2024 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.compound.previews + +import androidx.compose.material3.ColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import kotlinx.collections.immutable.persistentMapOf + +@Composable +internal fun ColorsSchemePreview( + backgroundColor: Color, + foregroundColor: Color, + colorScheme: ColorScheme, + modifier: Modifier = Modifier, +) { + val colors = persistentMapOf( + "primary" to colorScheme.primary, + "onPrimary" to colorScheme.onPrimary, + "primaryContainer" to colorScheme.primaryContainer, + "onPrimaryContainer" to colorScheme.onPrimaryContainer, + "inversePrimary" to colorScheme.inversePrimary, + "secondary" to colorScheme.secondary, + "onSecondary" to colorScheme.onSecondary, + "secondaryContainer" to colorScheme.secondaryContainer, + "onSecondaryContainer" to colorScheme.onSecondaryContainer, + "tertiary" to colorScheme.tertiary, + "onTertiary" to colorScheme.onTertiary, + "tertiaryContainer" to colorScheme.tertiaryContainer, + "onTertiaryContainer" to colorScheme.onTertiaryContainer, + "background" to colorScheme.background, + "onBackground" to colorScheme.onBackground, + "surface" to colorScheme.surface, + "onSurface" to colorScheme.onSurface, + "surfaceVariant" to colorScheme.surfaceVariant, + "onSurfaceVariant" to colorScheme.onSurfaceVariant, + "surfaceTint" to colorScheme.surfaceTint, + "inverseSurface" to colorScheme.inverseSurface, + "inverseOnSurface" to colorScheme.inverseOnSurface, + "error" to colorScheme.error, + "onError" to colorScheme.onError, + "errorContainer" to colorScheme.errorContainer, + "onErrorContainer" to colorScheme.onErrorContainer, + "outline" to colorScheme.outline, + "outlineVariant" to colorScheme.outlineVariant, + "scrim" to colorScheme.scrim, + ) + ColorListPreview( + backgroundColor = backgroundColor, + foregroundColor = foregroundColor, + colors = colors, + modifier = modifier, + ) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt new file mode 100644 index 0000000000..6e7b8ea825 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt @@ -0,0 +1,141 @@ +/* + * Copyright 2023, 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.compound.previews + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons + +@Preview(widthDp = 730, heightDp = 1800) +@Composable +internal fun IconsCompoundPreviewLight() = ElementTheme { + IconsCompoundPreview() +} + +@Preview(widthDp = 730, heightDp = 1800) +@Composable +internal fun IconsCompoundPreviewRtl() = ElementTheme { + CompositionLocalProvider( + LocalLayoutDirection provides LayoutDirection.Rtl, + ) { + IconsCompoundPreview( + title = "Compound Icons Rtl", + ) + } +} + +@Preview(widthDp = 730, heightDp = 1800) +@Composable +internal fun IconsCompoundPreviewDark() = ElementTheme(darkTheme = true) { + IconsCompoundPreview() +} + +@Composable +private fun IconsCompoundPreview( + title: String = "Compound Icons", +) { + val context = LocalContext.current + val content: Sequence<@Composable ColumnScope.() -> Unit> = sequence { + for (icon in CompoundIcons.allResIds) { + yield { + Icon( + modifier = Modifier.size(32.dp), + imageVector = ImageVector.vectorResource(icon), + contentDescription = null, + ) + Text( + modifier = Modifier.fillMaxWidth(), + text = context.resources.getResourceEntryName(icon) + .removePrefix("ic_compound_") + .replace("_", " "), + textAlign = TextAlign.Center, + style = ElementTheme.typography.fontBodyXsMedium, + color = ElementTheme.colors.textSecondary, + ) + } + } + } + IconsPreview( + title = title, + content = content.toList(), + ) +} + +@Composable +internal fun IconsPreview( + title: String, + content: List<@Composable ColumnScope.() -> Unit>, +) = Surface { + Column( + modifier = Modifier + .background(MaterialTheme.colorScheme.surfaceVariant) + .padding(16.dp) + .width(IntrinsicSize.Max), + verticalArrangement = Arrangement.spacedBy(6.dp), + ) { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp), + style = ElementTheme.typography.fontHeadingSmMedium, + text = title, + textAlign = TextAlign.Center, + ) + content.chunked(10).forEach { chunk -> + Row( + modifier = Modifier.height(IntrinsicSize.Max), + // Keep same order of icons for an easier comparison of previews + horizontalArrangement = Arrangement.Absolute.Left, + ) { + chunk.forEachIndexed { index, icon -> + Column( + modifier = Modifier + .background(MaterialTheme.colorScheme.background) + .fillMaxHeight() + .width(64.dp) + .padding(4.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + icon() + } + if (index < chunk.size - 1) { + Spacer(modifier = Modifier.width(6.dp)) + } + } + } + } + } +} \ No newline at end of file diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/SemanticColorsPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/SemanticColorsPreview.kt new file mode 100644 index 0000000000..d641ff39c5 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/SemanticColorsPreview.kt @@ -0,0 +1,205 @@ +/* + * 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.compound.previews + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.compoundColorsHcDark +import kotlinx.collections.immutable.ImmutableMap +import kotlinx.collections.immutable.persistentMapOf + +@Preview(heightDp = 2000) +@Composable +internal fun CompoundSemanticColorsLight() = ElementTheme { + Surface { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text("Compound Semantic Colors - Light") + ColorListPreview( + backgroundColor = Color.White, + foregroundColor = Color.Black, + colors = getSemanticColors(), + numColumns = 2, + ) + } + } +} + +@Preview(heightDp = 2000) +@Composable +internal fun CompoundSemanticColorsLightHc() = ElementTheme( + compoundDark = compoundColorsHcDark, +) { + Surface { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text("Compound Semantic Colors - Light HC") + ColorListPreview( + backgroundColor = Color.White, + foregroundColor = Color.Black, + colors = getSemanticColors(), + numColumns = 2, + ) + } + } +} + +@Preview(heightDp = 2000) +@Composable +internal fun CompoundSemanticColorsDark() = ElementTheme(darkTheme = true) { + Surface { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text("Compound Semantic Colors - Dark") + ColorListPreview( + backgroundColor = Color.White, + foregroundColor = Color.Black, + colors = getSemanticColors(), + numColumns = 2, + ) + } + } +} + +@Preview(heightDp = 2000) +@Composable +internal fun CompoundSemanticColorsDarkHc() = ElementTheme( + darkTheme = true, + compoundDark = compoundColorsHcDark, +) { + Surface { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text("Compound Semantic Colors - Dark HC") + ColorListPreview( + backgroundColor = Color.White, + foregroundColor = Color.Black, + colors = getSemanticColors(), + numColumns = 2, + ) + } + } +} + +@Composable +private fun getSemanticColors(): ImmutableMap { + return with(ElementTheme.colors) { + persistentMapOf( + "bgAccentHovered" to bgAccentHovered, + "bgAccentPressed" to bgAccentPressed, + "bgAccentRest" to bgAccentRest, + "bgAccentSelected" to bgAccentSelected, + "bgActionPrimaryDisabled" to bgActionPrimaryDisabled, + "bgActionPrimaryHovered" to bgActionPrimaryHovered, + "bgActionPrimaryPressed" to bgActionPrimaryPressed, + "bgActionPrimaryRest" to bgActionPrimaryRest, + "bgActionSecondaryHovered" to bgActionSecondaryHovered, + "bgActionSecondaryPressed" to bgActionSecondaryPressed, + "bgActionSecondaryRest" to bgActionSecondaryRest, + "bgBadgeAccent" to bgBadgeAccent, + "bgBadgeDefault" to bgBadgeDefault, + "bgBadgeInfo" to bgBadgeInfo, + "bgCanvasDefault" to bgCanvasDefault, + "bgCanvasDefaultLevel1" to bgCanvasDefaultLevel1, + "bgCanvasDisabled" to bgCanvasDisabled, + "bgCriticalHovered" to bgCriticalHovered, + "bgCriticalPrimary" to bgCriticalPrimary, + "bgCriticalSubtle" to bgCriticalSubtle, + "bgCriticalSubtleHovered" to bgCriticalSubtleHovered, + "bgDecorative1" to bgDecorative1, + "bgDecorative2" to bgDecorative2, + "bgDecorative3" to bgDecorative3, + "bgDecorative4" to bgDecorative4, + "bgDecorative5" to bgDecorative5, + "bgDecorative6" to bgDecorative6, + "bgInfoSubtle" to bgInfoSubtle, + "bgSubtlePrimary" to bgSubtlePrimary, + "bgSubtleSecondary" to bgSubtleSecondary, + "bgSubtleSecondaryLevel0" to bgSubtleSecondaryLevel0, + "bgSuccessSubtle" to bgSuccessSubtle, + "borderAccentSubtle" to borderAccentSubtle, + "borderCriticalHovered" to borderCriticalHovered, + "borderCriticalPrimary" to borderCriticalPrimary, + "borderCriticalSubtle" to borderCriticalSubtle, + "borderDisabled" to borderDisabled, + "borderFocused" to borderFocused, + "borderInfoSubtle" to borderInfoSubtle, + "borderInteractiveHovered" to borderInteractiveHovered, + "borderInteractivePrimary" to borderInteractivePrimary, + "borderInteractiveSecondary" to borderInteractiveSecondary, + "borderSuccessSubtle" to borderSuccessSubtle, + "gradientActionStop1" to gradientActionStop1, + "gradientActionStop2" to gradientActionStop2, + "gradientActionStop3" to gradientActionStop3, + "gradientActionStop4" to gradientActionStop4, + "gradientInfoStop1" to gradientInfoStop1, + "gradientInfoStop2" to gradientInfoStop2, + "gradientInfoStop3" to gradientInfoStop3, + "gradientInfoStop4" to gradientInfoStop4, + "gradientInfoStop5" to gradientInfoStop5, + "gradientInfoStop6" to gradientInfoStop6, + "gradientSubtleStop1" to gradientSubtleStop1, + "gradientSubtleStop2" to gradientSubtleStop2, + "gradientSubtleStop3" to gradientSubtleStop3, + "gradientSubtleStop4" to gradientSubtleStop4, + "gradientSubtleStop5" to gradientSubtleStop5, + "gradientSubtleStop6" to gradientSubtleStop6, + "iconAccentPrimary" to iconAccentPrimary, + "iconAccentTertiary" to iconAccentTertiary, + "iconCriticalPrimary" to iconCriticalPrimary, + "iconDisabled" to iconDisabled, + "iconInfoPrimary" to iconInfoPrimary, + "iconOnSolidPrimary" to iconOnSolidPrimary, + "iconPrimary" to iconPrimary, + "iconPrimaryAlpha" to iconPrimaryAlpha, + "iconQuaternary" to iconQuaternary, + "iconQuaternaryAlpha" to iconQuaternaryAlpha, + "iconSecondary" to iconSecondary, + "iconSecondaryAlpha" to iconSecondaryAlpha, + "iconSuccessPrimary" to iconSuccessPrimary, + "iconTertiary" to iconTertiary, + "iconTertiaryAlpha" to iconTertiaryAlpha, + "textActionAccent" to textActionAccent, + "textActionPrimary" to textActionPrimary, + "textBadgeAccent" to textBadgeAccent, + "textBadgeInfo" to textBadgeInfo, + "textCriticalPrimary" to textCriticalPrimary, + "textDecorative1" to textDecorative1, + "textDecorative2" to textDecorative2, + "textDecorative3" to textDecorative3, + "textDecorative4" to textDecorative4, + "textDecorative5" to textDecorative5, + "textDecorative6" to textDecorative6, + "textDisabled" to textDisabled, + "textInfoPrimary" to textInfoPrimary, + "textLinkExternal" to textLinkExternal, + "textOnSolidPrimary" to textOnSolidPrimary, + "textPrimary" to textPrimary, + "textSecondary" to textSecondary, + "textSuccessPrimary" to textSuccessPrimary, + "isLight" to if (isLight) Color.White else Color.Black, + ) + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt new file mode 100644 index 0000000000..2fc93aeef0 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt @@ -0,0 +1,49 @@ +/* + * 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.compound.previews + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme + +@Preview +@Composable +fun TypographyPreview() = ElementTheme { + Surface { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + with(ElementTheme.materialTypography) { + TypographyTokenPreview(displayLarge, "Display large") + TypographyTokenPreview(displayMedium, "Display medium") + TypographyTokenPreview(displaySmall, "Display small") + TypographyTokenPreview(headlineLarge, "Headline large") + TypographyTokenPreview(headlineMedium, "Headline medium") + TypographyTokenPreview(headlineSmall, "Headline small") + TypographyTokenPreview(titleLarge, "Title large") + TypographyTokenPreview(titleMedium, "Title medium") + TypographyTokenPreview(titleSmall, "Title small") + TypographyTokenPreview(bodyLarge, "Body large") + TypographyTokenPreview(bodyMedium, "Body medium") + TypographyTokenPreview(bodySmall, "Body small") + TypographyTokenPreview(labelLarge, "Label large") + TypographyTokenPreview(labelMedium, "Label medium") + TypographyTokenPreview(labelSmall, "Label small") + } + } + } +} + +@Composable +private fun TypographyTokenPreview(style: TextStyle, text: String) { + Text(text = text, style = style) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/showkase/CompoundShowkaseRootModule.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/showkase/CompoundShowkaseRootModule.kt new file mode 100644 index 0000000000..f1c7b3f8d7 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/showkase/CompoundShowkaseRootModule.kt @@ -0,0 +1,14 @@ +/* + * 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.compound.showkase + +import com.airbnb.android.showkase.annotation.ShowkaseRoot +import com.airbnb.android.showkase.annotation.ShowkaseRootModule + +@ShowkaseRoot +class CompoundShowkaseRootModule : ShowkaseRootModule diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt new file mode 100644 index 0000000000..9b2ea07376 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2023, 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.compound.theme + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp + +/** + * Data class to hold avatar colors. + */ +data class AvatarColors( + /** Background color for the avatar. */ + val background: Color, + /** Foreground color for the avatar. */ + val foreground: Color, +) + +/** + * Avatar colors using semantic tokens. + */ +@Composable +fun avatarColors(): List { + return listOf( + AvatarColors(background = ElementTheme.colors.bgDecorative1, foreground = ElementTheme.colors.textDecorative1), + AvatarColors(background = ElementTheme.colors.bgDecorative2, foreground = ElementTheme.colors.textDecorative2), + AvatarColors(background = ElementTheme.colors.bgDecorative3, foreground = ElementTheme.colors.textDecorative3), + AvatarColors(background = ElementTheme.colors.bgDecorative4, foreground = ElementTheme.colors.textDecorative4), + AvatarColors(background = ElementTheme.colors.bgDecorative5, foreground = ElementTheme.colors.textDecorative5), + AvatarColors(background = ElementTheme.colors.bgDecorative6, foreground = ElementTheme.colors.textDecorative6), + ) +} + +@Preview +@Composable +internal fun AvatarColorsPreviewLight() { + ElementTheme { + val chunks = avatarColors().chunked(4) + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + for (chunk in chunks) { + AvatarColorRow(chunk) + } + } + } +} + +@Preview +@Composable +internal fun AvatarColorsPreviewDark() { + ElementTheme(darkTheme = true) { + val chunks = avatarColors().chunked(4) + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + for (chunk in chunks) { + AvatarColorRow(chunk) + } + } + } +} + +@Composable +private fun AvatarColorRow(colors: List) { + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + colors.forEach { color -> + Box( + modifier = Modifier.size(48.dp) + .background(color.background), + ) { + Text( + modifier = Modifier.align(Alignment.Center), + text = "A", + color = color.foreground, + ) + } + } + } +} \ No newline at end of file diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt new file mode 100644 index 0000000000..63994f24e9 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt @@ -0,0 +1,165 @@ +/* + * Copyright 2023, 2024 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.compound.theme + +import android.os.Build +import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Typography +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import io.element.android.compound.tokens.compoundTypography +import io.element.android.compound.tokens.generated.SemanticColors +import io.element.android.compound.tokens.generated.TypographyTokens +import io.element.android.compound.tokens.generated.compoundColorsDark +import io.element.android.compound.tokens.generated.compoundColorsLight + +/** + * Inspired from https://medium.com/@lucasyujideveloper/54cbcbde1ace + */ +object ElementTheme { + /** + * The current [SemanticColors] provided by [ElementTheme]. + * These come from Compound and are the recommended colors to use for custom components. + * In Figma, these colors usually have the `Light/` or `Dark/` prefix. + */ + val colors: SemanticColors + @Composable + @ReadOnlyComposable + get() = LocalCompoundColors.current + + /** + * The current Material 3 [ColorScheme] provided by [ElementTheme], coming from [MaterialTheme]. + * In Figma, these colors usually have the `M3/` prefix. + */ + val materialColors: ColorScheme + @Composable + @ReadOnlyComposable + get() = MaterialTheme.colorScheme + + /** + * Compound [Typography] tokens. In Figma, these have the `Android/font/` prefix. + */ + val typography: TypographyTokens = TypographyTokens + + /** + * Material 3 [Typography] tokens. In Figma, these have the `M3 Typography/` prefix. + */ + val materialTypography: Typography + @Composable + @ReadOnlyComposable + get() = MaterialTheme.typography + + /** + * Returns whether the theme version used is the light or the dark one. + */ + val isLightTheme: Boolean + @Composable + @ReadOnlyComposable + get() = LocalCompoundColors.current.isLight +} + +/* Global variables (application level) */ +internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLight } + +/** + * Sets up the theme for the application, or a part of it. + * + * @param darkTheme whether to use the dark theme or not. If `true`, the dark theme will be used. + * @param applySystemBarsUpdate whether to update the system bars color scheme or not when the theme changes. It's `true` by default. + * This is specially useful when you want to apply an alternate theme to a part of the app but don't want it to affect the system bars. + * @param lightStatusBar whether to use a light status bar color scheme or not. By default, it's the opposite of [darkTheme]. + * @param dynamicColor whether to enable MaterialYou or not. It's `false` by default. + * @param compoundLight the [SemanticColors] to use in light theme. + * @param compoundDark the [SemanticColors] to use in dark theme. + * @param materialColorsLight the Material 3 [ColorScheme] to use in light theme. + * @param materialColorsDark the Material 3 [ColorScheme] to use in dark theme. + * @param typography the Material 3 [Typography] tokens to use. It'll use [compoundTypography] by default. + * @param content the content to apply the theme to. + */ +@Composable +fun ElementTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + applySystemBarsUpdate: Boolean = true, + lightStatusBar: Boolean = !darkTheme, + dynamicColor: Boolean = false, /* true to enable MaterialYou */ + compoundLight: SemanticColors = compoundColorsLight, + compoundDark: SemanticColors = compoundColorsDark, + materialColorsLight: ColorScheme = compoundLight.toMaterialColorScheme(), + materialColorsDark: ColorScheme = compoundDark.toMaterialColorScheme(), + typography: Typography = compoundTypography, + content: @Composable () -> Unit, +) { + val currentCompoundColor = when { + darkTheme -> compoundDark + else -> compoundLight + } + + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + darkTheme -> materialColorsDark + else -> materialColorsLight + } + + val statusBarColorScheme = if (dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val context = LocalContext.current + if (lightStatusBar) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } + } else { + colorScheme + } + + if (applySystemBarsUpdate) { + val activity = LocalContext.current as? ComponentActivity + LaunchedEffect(statusBarColorScheme, darkTheme, lightStatusBar) { + activity?.enableEdgeToEdge( + // For Status bar use the background color of the app + statusBarStyle = SystemBarStyle.auto( + lightScrim = statusBarColorScheme.background.toArgb(), + darkScrim = statusBarColorScheme.background.toArgb(), + detectDarkMode = { !lightStatusBar } + ), + // For Navigation bar use a transparent color so the content can be seen through it + navigationBarStyle = if (darkTheme) { + SystemBarStyle.dark(Color.Transparent.toArgb()) + } else { + SystemBarStyle.light(Color.Transparent.toArgb(), Color.Transparent.toArgb()) + } + ) + } + } + CompositionLocalProvider( + LocalCompoundColors provides currentCompoundColor, + LocalContentColor provides colorScheme.onSurface, + ) { + MaterialTheme( + colorScheme = colorScheme, + typography = typography, + content = content + ) + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt new file mode 100644 index 0000000000..fce1a920d0 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2023, 2024 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.compound.theme + +import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle +import androidx.activity.enableEdgeToEdge +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext + +/** + * Can be used to force a composable in dark theme. + * It will automatically change the system ui colors back to normal when leaving the composition. + */ +@Composable +fun ForcedDarkElementTheme( + lightStatusBar: Boolean = false, + content: @Composable () -> Unit, +) { + val colorScheme = MaterialTheme.colorScheme + val wasDarkTheme = !ElementTheme.colors.isLight + val activity = LocalContext.current as? ComponentActivity + DisposableEffect(Unit) { + onDispose { + activity?.enableEdgeToEdge( + statusBarStyle = SystemBarStyle.auto( + lightScrim = colorScheme.background.toArgb(), + darkScrim = colorScheme.background.toArgb(), + ), + navigationBarStyle = if (wasDarkTheme) { + SystemBarStyle.dark(Color.Transparent.toArgb()) + } else { + SystemBarStyle.light( + scrim = Color.Transparent.toArgb(), + darkScrim = Color.Transparent.toArgb() + ) + } + ) + } + } + ElementTheme(darkTheme = true, lightStatusBar = lightStatusBar, content = content) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/LegacyColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/LegacyColors.kt new file mode 100644 index 0000000000..6b7814d1e3 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/LegacyColors.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2023, 2024 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.compound.theme + +import androidx.compose.ui.graphics.Color +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.internal.DarkColorTokens +import io.element.android.compound.tokens.generated.internal.LightColorTokens + +// ================================================================================================= +// IMPORTANT! +// We should not be adding any new colors here. This file is only for legacy colors. +// In fact, we should try to remove any references to these colors as we +// iterate through the designs. All new colors should come from Compound's Design Tokens. +// ================================================================================================= + +val LinkColor = Color(0xFF0086E6) + +@OptIn(CoreColorToken::class) +val SnackBarLabelColorLight = LightColorTokens.colorGray700 +@OptIn(CoreColorToken::class) +val SnackBarLabelColorDark = DarkColorTokens.colorGray700 diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeDark.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeDark.kt new file mode 100644 index 0000000000..7ee6b631b5 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeDark.kt @@ -0,0 +1,52 @@ +/* + * 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.compound.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.darkColorScheme +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.SemanticColors +import io.element.android.compound.tokens.generated.internal.DarkColorTokens + +/** + * See the mapping in + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=311-14&p=f&t=QcVyNaPEZMDA6RFK-0 + */ +@OptIn(CoreColorToken::class) +fun SemanticColors.toMaterialColorSchemeDark(): ColorScheme = darkColorScheme( + primary = bgActionPrimaryRest, + onPrimary = textOnSolidPrimary, + primaryContainer = bgCanvasDefault, + onPrimaryContainer = textPrimary, + inversePrimary = textOnSolidPrimary, + secondary = textSecondary, + onSecondary = textOnSolidPrimary, + secondaryContainer = bgSubtlePrimary, + onSecondaryContainer = textPrimary, + tertiary = textSecondary, + onTertiary = textOnSolidPrimary, + tertiaryContainer = bgActionPrimaryRest, + onTertiaryContainer = textOnSolidPrimary, + background = bgCanvasDefault, + onBackground = textPrimary, + surface = bgCanvasDefault, + onSurface = textPrimary, + surfaceVariant = bgSubtleSecondary, + onSurfaceVariant = textSecondary, + surfaceTint = DarkColorTokens.colorGray1000, + inverseSurface = DarkColorTokens.colorGray1300, + inverseOnSurface = textOnSolidPrimary, + error = textCriticalPrimary, + onError = textOnSolidPrimary, + errorContainer = DarkColorTokens.colorRed400, + onErrorContainer = textCriticalPrimary, + outline = borderInteractivePrimary, + outlineVariant = DarkColorTokens.colorAlphaGray400, + // Note: for light it will be colorGray1400 + scrim = DarkColorTokens.colorGray300, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeLight.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeLight.kt new file mode 100644 index 0000000000..b179234429 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialColorSchemeLight.kt @@ -0,0 +1,52 @@ +/* + * 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.compound.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.lightColorScheme +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.SemanticColors +import io.element.android.compound.tokens.generated.internal.LightColorTokens + +/** + * See the mapping in + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=311-14&p=f&t=QcVyNaPEZMDA6RFK-0 + */ +@OptIn(CoreColorToken::class) +fun SemanticColors.toMaterialColorSchemeLight(): ColorScheme = lightColorScheme( + primary = bgActionPrimaryRest, + onPrimary = textOnSolidPrimary, + primaryContainer = bgCanvasDefault, + onPrimaryContainer = textPrimary, + inversePrimary = textOnSolidPrimary, + secondary = textSecondary, + onSecondary = textOnSolidPrimary, + secondaryContainer = bgSubtlePrimary, + onSecondaryContainer = textPrimary, + tertiary = textSecondary, + onTertiary = textOnSolidPrimary, + tertiaryContainer = bgActionPrimaryRest, + onTertiaryContainer = textOnSolidPrimary, + background = bgCanvasDefault, + onBackground = textPrimary, + surface = bgCanvasDefault, + onSurface = textPrimary, + surfaceVariant = bgSubtleSecondary, + onSurfaceVariant = textSecondary, + surfaceTint = LightColorTokens.colorGray1000, + inverseSurface = LightColorTokens.colorGray1300, + inverseOnSurface = textOnSolidPrimary, + error = textCriticalPrimary, + onError = textOnSolidPrimary, + errorContainer = LightColorTokens.colorRed400, + onErrorContainer = textCriticalPrimary, + outline = borderInteractivePrimary, + outlineVariant = LightColorTokens.colorAlphaGray400, + // Note: for dark it will be colorGray300 + scrim = LightColorTokens.colorGray1400, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt new file mode 100644 index 0000000000..12f4cd18f8 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt @@ -0,0 +1,139 @@ +/* + * 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.compound.theme + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.compound.utils.toHrf + +@Preview(heightDp = 1200, widthDp = 420) +@Composable +internal fun MaterialTextPreview() = Row( + modifier = Modifier.background(Color.Yellow) +) { + MaterialPreview( + modifier = Modifier.weight(1f), + darkTheme = false, + ) + MaterialPreview( + modifier = Modifier.weight(1f), + darkTheme = true, + ) +} + +private data class Model( + val name: String, + val bgColor: Color, + val textColor: Color, +) + +@Composable +private fun MaterialPreview( + darkTheme: Boolean, + modifier: Modifier = Modifier, +) = Column(modifier = modifier) { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + textAlign = TextAlign.Center, + text = if (darkTheme) "Dark" else "Light", + color = Color.Black, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + ) + ElementTheme( + darkTheme = darkTheme, + ) { + Column( + modifier = Modifier.fillMaxSize() + ) { + listOf( + Model("Background", MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.onBackground), + Model("Primary", MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.onPrimary), + Model("PrimaryContainer", MaterialTheme.colorScheme.primaryContainer, MaterialTheme.colorScheme.onPrimaryContainer), + Model("Secondary", MaterialTheme.colorScheme.secondary, MaterialTheme.colorScheme.onSecondary), + Model("SecondaryContainer", MaterialTheme.colorScheme.secondaryContainer, MaterialTheme.colorScheme.onSecondaryContainer), + Model("Tertiary", MaterialTheme.colorScheme.tertiary, MaterialTheme.colorScheme.onTertiary), + Model("TertiaryContainer", MaterialTheme.colorScheme.tertiaryContainer, MaterialTheme.colorScheme.onTertiaryContainer), + Model("Surface", MaterialTheme.colorScheme.surface, MaterialTheme.colorScheme.onSurface), + Model("SurfaceVariant", MaterialTheme.colorScheme.surfaceVariant, MaterialTheme.colorScheme.onSurfaceVariant), + Model("InverseSurface", MaterialTheme.colorScheme.inverseSurface, MaterialTheme.colorScheme.inverseOnSurface), + Model("Error", MaterialTheme.colorScheme.error, MaterialTheme.colorScheme.onError), + Model("ErrorContainer", MaterialTheme.colorScheme.errorContainer, MaterialTheme.colorScheme.onErrorContainer), + ).forEach { + TextPreview( + name = it.name, + bgColor = it.bgColor, + textColor = it.textColor, + ) + } + Box( + modifier = Modifier + .padding(1.dp) + .fillMaxWidth() + .background(MaterialTheme.colorScheme.background) + ) { + Text( + text = "Below\n".repeat(3), + color = MaterialTheme.colorScheme.onBackground, + ) + Text( + modifier = Modifier + .padding(12.dp) + .fillMaxWidth() + // the alpha applied to the scrim color does not seem to be mandatory. + // The library ignores the alpha level provided and apply it's own. + // For testing the color, manually set an alpha. + .background(color = MaterialTheme.colorScheme.scrim.copy(alpha = 0.32f)) + .padding(16.dp), + text = "${"Scrim"}\n${MaterialTheme.colorScheme.scrim.toHrf()}", + style = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace), + textAlign = TextAlign.Center, + color = MaterialTheme.colorScheme.onBackground, + ) + } + } + } +} + + +@Composable +private fun TextPreview( + name: String, + bgColor: Color, + textColor: Color, + modifier: Modifier = Modifier, +) = Text( + modifier = modifier + .padding(1.dp) + .fillMaxWidth() + .background(bgColor) + .padding(horizontal = 16.dp, vertical = 8.dp), + text = "$name\n${textColor.toHrf()}\n${bgColor.toHrf()}", + style = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace), + textAlign = TextAlign.Center, + color = textColor, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialThemeColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialThemeColors.kt new file mode 100644 index 0000000000..f81b0a94f6 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialThemeColors.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2023, 2024 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.compound.theme + +import androidx.compose.material3.ColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import io.element.android.compound.previews.ColorsSchemePreview +import io.element.android.compound.tokens.generated.SemanticColors +import io.element.android.compound.tokens.generated.compoundColorsHcDark +import io.element.android.compound.tokens.generated.compoundColorsHcLight + +fun SemanticColors.toMaterialColorScheme(): ColorScheme { + return if (isLight) { + toMaterialColorSchemeLight() + } else { + toMaterialColorSchemeDark() + } +} + +@Preview(heightDp = 1200) +@Composable +internal fun ColorsSchemeLightPreview() = ElementTheme { + ColorsSchemePreview( + Color.Black, + Color.White, + ElementTheme.materialColors, + ) +} + +@Preview(heightDp = 1200) +@Composable +internal fun ColorsSchemeLightHcPreview() = ElementTheme( + compoundLight = compoundColorsHcLight, +) { + ColorsSchemePreview( + Color.Black, + Color.White, + ElementTheme.materialColors, + ) +} + +@Preview(heightDp = 1200) +@Composable +internal fun ColorsSchemeDarkPreview() = ElementTheme( + darkTheme = true, +) { + ColorsSchemePreview( + Color.White, + Color.Black, + ElementTheme.materialColors, + ) +} + +@Preview(heightDp = 1200) +@Composable +internal fun ColorsSchemeDarkHcPreview() = ElementTheme( + darkTheme = true, + compoundDark = compoundColorsHcDark, +) { + ColorsSchemePreview( + Color.White, + Color.Black, + ElementTheme.materialColors, + ) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt new file mode 100644 index 0000000000..03ca5c598f --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2023, 2024 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.compound.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +enum class Theme { + System, + Dark, + Light; +} + +val themes = listOf(Theme.System, Theme.Dark, Theme.Light) + +@Composable +fun Theme.isDark(): Boolean { + return when (this) { + Theme.System -> isSystemInDarkTheme() + Theme.Dark -> true + Theme.Light -> false + } +} + +fun Flow.mapToTheme(): Flow = map { + when (it) { + null -> Theme.System + else -> Theme.valueOf(it) + } +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/CompoundTypography.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/CompoundTypography.kt new file mode 100644 index 0000000000..ab4d898ba4 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/CompoundTypography.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2023, 2024 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.compound.tokens + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.PlatformTextStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.em +import androidx.compose.ui.unit.sp +import com.airbnb.android.showkase.annotation.ShowkaseTypography +import io.element.android.compound.tokens.generated.TypographyTokens + +// 32px (Material) vs 34px, it's the closest one +@ShowkaseTypography(name = "M3 Headline Large", group = "Compound") +internal val compoundHeadingXlRegular = TypographyTokens.fontHeadingXlRegular + +// both are 28px +@ShowkaseTypography(name = "M3 Headline Medium", group = "Compound") +internal val compoundHeadingLgRegular = TypographyTokens.fontHeadingLgRegular + +// These are the default M3 values, but we're setting them manually so an update in M3 doesn't break our designs +@ShowkaseTypography(name = "M3 Headline Small", group = "Compound") +internal val defaultHeadlineSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + lineHeight = 32.sp, + fontSize = 24.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) +) + +// 22px (Material) vs 20px, it's the closest one +@ShowkaseTypography(name = "M3 Title Large", group = "Compound") +internal val compoundHeadingMdRegular = TypographyTokens.fontHeadingMdRegular + +// 16px both +@ShowkaseTypography(name = "M3 Title Medium", group = "Compound") +internal val compoundBodyLgMedium = TypographyTokens.fontBodyLgMedium + +// 14px both +@ShowkaseTypography(name = "M3 Title Small", group = "Compound") +internal val compoundBodyMdMedium = TypographyTokens.fontBodyMdMedium + +// 16px both +@ShowkaseTypography(name = "M3 Body Large", group = "Compound") +internal val compoundBodyLgRegular = TypographyTokens.fontBodyLgRegular + +// 14px both +@ShowkaseTypography(name = "M3 Body Medium", group = "Compound") +internal val compoundBodyMdRegular = TypographyTokens.fontBodyMdRegular + +// 12px both +@ShowkaseTypography(name = "M3 Body Small", group = "Compound") +internal val compoundBodySmRegular = TypographyTokens.fontBodySmRegular + +// 14px both, Title Small uses the same token so we have to declare it twice +@ShowkaseTypography(name = "M3 Label Large", group = "Compound") +internal val compoundBodyMdMedium_LabelLarge = TypographyTokens.fontBodyMdMedium + +// 12px both +@ShowkaseTypography(name = "M3 Label Medium", group = "Compound") +internal val compoundBodySmMedium = TypographyTokens.fontBodySmMedium + +// 11px both +@ShowkaseTypography(name = "M3 Label Small", group = "Compound") +internal val compoundBodyXsMedium = TypographyTokens.fontBodyXsMedium + +internal val compoundTypography = Typography( + // displayLarge = , 57px (Material) size. We have no equivalent + // displayMedium = , 45px (Material) size. We have no equivalent + // displaySmall = , 36px (Material) size. We have no equivalent + headlineLarge = compoundHeadingXlRegular, + headlineMedium = compoundHeadingLgRegular, + headlineSmall = defaultHeadlineSmall, + titleLarge = compoundHeadingMdRegular, + titleMedium = compoundBodyLgMedium, + titleSmall = compoundBodyMdMedium, + bodyLarge = compoundBodyLgRegular, + bodyMedium = compoundBodyMdRegular, + bodySmall = compoundBodySmRegular, + labelLarge = compoundBodyMdMedium_LabelLarge, + labelMedium = compoundBodySmMedium, + labelSmall = compoundBodyXsMedium, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/CompoundIcons.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/CompoundIcons.kt new file mode 100644 index 0000000000..76b3275651 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/CompoundIcons.kt @@ -0,0 +1,1034 @@ +/* + * 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. + */ + + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import io.element.android.compound.R +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import kotlinx.collections.immutable.persistentListOf + +object CompoundIcons { + @Composable fun Admin(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_admin) + } + @Composable fun ArrowDown(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_arrow_down) + } + @Composable fun ArrowLeft(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_arrow_left) + } + @Composable fun ArrowRight(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_arrow_right) + } + @Composable fun ArrowUp(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_arrow_up) + } + @Composable fun ArrowUpRight(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_arrow_up_right) + } + @Composable fun AskToJoin(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_ask_to_join) + } + @Composable fun AskToJoinSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_ask_to_join_solid) + } + @Composable fun Attachment(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_attachment) + } + @Composable fun Audio(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_audio) + } + @Composable fun Block(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_block) + } + @Composable fun Bold(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_bold) + } + @Composable fun Calendar(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_calendar) + } + @Composable fun Chart(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chart) + } + @Composable fun Chat(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chat) + } + @Composable fun ChatNew(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chat_new) + } + @Composable fun ChatProblem(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chat_problem) + } + @Composable fun ChatSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chat_solid) + } + @Composable fun Check(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_check) + } + @Composable fun CheckCircle(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_check_circle) + } + @Composable fun CheckCircleSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_check_circle_solid) + } + @Composable fun ChevronDown(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chevron_down) + } + @Composable fun ChevronLeft(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chevron_left) + } + @Composable fun ChevronRight(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chevron_right) + } + @Composable fun ChevronUp(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chevron_up) + } + @Composable fun ChevronUpDown(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_chevron_up_down) + } + @Composable fun Circle(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_circle) + } + @Composable fun Close(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_close) + } + @Composable fun Cloud(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_cloud) + } + @Composable fun CloudSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_cloud_solid) + } + @Composable fun Code(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_code) + } + @Composable fun Collapse(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_collapse) + } + @Composable fun Company(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_company) + } + @Composable fun Compose(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_compose) + } + @Composable fun Computer(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_computer) + } + @Composable fun Copy(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_copy) + } + @Composable fun DarkMode(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_dark_mode) + } + @Composable fun Delete(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_delete) + } + @Composable fun Devices(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_devices) + } + @Composable fun DialPad(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_dial_pad) + } + @Composable fun Document(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_document) + } + @Composable fun Download(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_download) + } + @Composable fun DownloadIos(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_download_ios) + } + @Composable fun DragGrid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_drag_grid) + } + @Composable fun DragList(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_drag_list) + } + @Composable fun Earpiece(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_earpiece) + } + @Composable fun Edit(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_edit) + } + @Composable fun EditSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_edit_solid) + } + @Composable fun Email(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_email) + } + @Composable fun EmailSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_email_solid) + } + @Composable fun EndCall(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_end_call) + } + @Composable fun Error(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_error) + } + @Composable fun ErrorSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_error_solid) + } + @Composable fun Expand(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_expand) + } + @Composable fun Explore(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_explore) + } + @Composable fun ExportArchive(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_export_archive) + } + @Composable fun Extensions(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_extensions) + } + @Composable fun ExtensionsSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_extensions_solid) + } + @Composable fun Favourite(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_favourite) + } + @Composable fun FavouriteSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_favourite_solid) + } + @Composable fun FileError(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_file_error) + } + @Composable fun Files(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_files) + } + @Composable fun Filter(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_filter) + } + @Composable fun Forward(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_forward) + } + @Composable fun Grid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_grid) + } + @Composable fun Group(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_group) + } + @Composable fun Guest(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_guest) + } + @Composable fun HeadphonesOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_headphones_off_solid) + } + @Composable fun HeadphonesSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_headphones_solid) + } + @Composable fun Help(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_help) + } + @Composable fun HelpSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_help_solid) + } + @Composable fun History(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_history) + } + @Composable fun Home(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_home) + } + @Composable fun HomeSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_home_solid) + } + @Composable fun Host(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_host) + } + @Composable fun Image(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_image) + } + @Composable fun ImageError(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_image_error) + } + @Composable fun IndentDecrease(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_indent_decrease) + } + @Composable fun IndentIncrease(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_indent_increase) + } + @Composable fun Info(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_info) + } + @Composable fun InfoSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_info_solid) + } + @Composable fun InlineCode(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_inline_code) + } + @Composable fun Italic(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_italic) + } + @Composable fun Key(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_key) + } + @Composable fun KeyOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_key_off) + } + @Composable fun KeyOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_key_off_solid) + } + @Composable fun KeySolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_key_solid) + } + @Composable fun Keyboard(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_keyboard) + } + @Composable fun Labs(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_labs) + } + @Composable fun Leave(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_leave) + } + @Composable fun Link(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_link) + } + @Composable fun Linux(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_linux) + } + @Composable fun ListBulleted(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_list_bulleted) + } + @Composable fun ListNumbered(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_list_numbered) + } + @Composable fun ListView(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_list_view) + } + @Composable fun LocationNavigator(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_location_navigator) + } + @Composable fun LocationNavigatorCentred(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_location_navigator_centred) + } + @Composable fun LocationPin(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_location_pin) + } + @Composable fun LocationPinSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_location_pin_solid) + } + @Composable fun Lock(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_lock) + } + @Composable fun LockOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_lock_off) + } + @Composable fun LockSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_lock_solid) + } + @Composable fun Mac(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mac) + } + @Composable fun MarkAsRead(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mark_as_read) + } + @Composable fun MarkAsUnread(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mark_as_unread) + } + @Composable fun MarkThreadsAsRead(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mark_threads_as_read) + } + @Composable fun MarkerReadReceipts(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_marker_read_receipts) + } + @Composable fun Mention(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mention) + } + @Composable fun Menu(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_menu) + } + @Composable fun MicOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mic_off) + } + @Composable fun MicOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mic_off_solid) + } + @Composable fun MicOn(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mic_on) + } + @Composable fun MicOnSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mic_on_solid) + } + @Composable fun Minus(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_minus) + } + @Composable fun Mobile(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_mobile) + } + @Composable fun Notifications(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_notifications) + } + @Composable fun NotificationsOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_notifications_off) + } + @Composable fun NotificationsOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_notifications_off_solid) + } + @Composable fun NotificationsSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_notifications_solid) + } + @Composable fun Offline(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_offline) + } + @Composable fun OverflowHorizontal(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_overflow_horizontal) + } + @Composable fun OverflowVertical(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_overflow_vertical) + } + @Composable fun Pause(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_pause) + } + @Composable fun PauseSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_pause_solid) + } + @Composable fun Pin(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_pin) + } + @Composable fun PinSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_pin_solid) + } + @Composable fun Play(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_play) + } + @Composable fun PlaySolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_play_solid) + } + @Composable fun Plus(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_plus) + } + @Composable fun Polls(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_polls) + } + @Composable fun PollsEnd(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_polls_end) + } + @Composable fun PopOut(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_pop_out) + } + @Composable fun Preferences(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_preferences) + } + @Composable fun PresenceOutline8X8(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_presence_outline_8_x_8) + } + @Composable fun PresenceSolid8X8(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_presence_solid_8_x_8) + } + @Composable fun PresenceStrikethrough8X8(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_presence_strikethrough_8_x_8) + } + @Composable fun Public(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_public) + } + @Composable fun QrCode(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_qr_code) + } + @Composable fun Quote(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_quote) + } + @Composable fun RaisedHandSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_raised_hand_solid) + } + @Composable fun Reaction(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_reaction) + } + @Composable fun ReactionAdd(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_reaction_add) + } + @Composable fun ReactionSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_reaction_solid) + } + @Composable fun Reply(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_reply) + } + @Composable fun Restart(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_restart) + } + @Composable fun Room(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_room) + } + @Composable fun Search(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_search) + } + @Composable fun Send(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_send) + } + @Composable fun SendSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_send_solid) + } + @Composable fun Settings(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_settings) + } + @Composable fun SettingsSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_settings_solid) + } + @Composable fun Share(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_share) + } + @Composable fun ShareAndroid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_share_android) + } + @Composable fun ShareIos(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_share_ios) + } + @Composable fun ShareScreen(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_share_screen) + } + @Composable fun ShareScreenSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_share_screen_solid) + } + @Composable fun Shield(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_shield) + } + @Composable fun Sidebar(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_sidebar) + } + @Composable fun SignOut(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_sign_out) + } + @Composable fun Spinner(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_spinner) + } + @Composable fun Spotlight(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_spotlight) + } + @Composable fun SpotlightView(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_spotlight_view) + } + @Composable fun Strikethrough(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_strikethrough) + } + @Composable fun SwitchCameraSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_switch_camera_solid) + } + @Composable fun TakePhoto(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_take_photo) + } + @Composable fun TakePhotoSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_take_photo_solid) + } + @Composable fun TextFormatting(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_text_formatting) + } + @Composable fun Threads(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_threads) + } + @Composable fun ThreadsSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_threads_solid) + } + @Composable fun Time(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_time) + } + @Composable fun Underline(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_underline) + } + @Composable fun Unknown(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_unknown) + } + @Composable fun UnknownSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_unknown_solid) + } + @Composable fun Unpin(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_unpin) + } + @Composable fun User(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user) + } + @Composable fun UserAdd(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user_add) + } + @Composable fun UserAddSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user_add_solid) + } + @Composable fun UserProfile(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user_profile) + } + @Composable fun UserProfileSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user_profile_solid) + } + @Composable fun UserSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_user_solid) + } + @Composable fun Verified(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_verified) + } + @Composable fun VideoCall(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call) + } + @Composable fun VideoCallDeclinedSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call_declined_solid) + } + @Composable fun VideoCallMissedSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call_missed_solid) + } + @Composable fun VideoCallOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call_off) + } + @Composable fun VideoCallOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call_off_solid) + } + @Composable fun VideoCallSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_video_call_solid) + } + @Composable fun VisibilityOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_visibility_off) + } + @Composable fun VisibilityOn(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_visibility_on) + } + @Composable fun VoiceCall(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_voice_call) + } + @Composable fun VoiceCallSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_voice_call_solid) + } + @Composable fun VolumeOff(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_volume_off) + } + @Composable fun VolumeOffSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_volume_off_solid) + } + @Composable fun VolumeOn(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_volume_on) + } + @Composable fun VolumeOnSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_volume_on_solid) + } + @Composable fun Warning(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_warning) + } + @Composable fun WebBrowser(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_web_browser) + } + @Composable fun Windows(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_windows) + } + @Composable fun Workspace(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_workspace) + } + @Composable fun WorkspaceSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_workspace_solid) + } + + val all @Composable get() = persistentListOf( + Admin(), + ArrowDown(), + ArrowLeft(), + ArrowRight(), + ArrowUp(), + ArrowUpRight(), + AskToJoin(), + AskToJoinSolid(), + Attachment(), + Audio(), + Block(), + Bold(), + Calendar(), + Chart(), + Chat(), + ChatNew(), + ChatProblem(), + ChatSolid(), + Check(), + CheckCircle(), + CheckCircleSolid(), + ChevronDown(), + ChevronLeft(), + ChevronRight(), + ChevronUp(), + ChevronUpDown(), + Circle(), + Close(), + Cloud(), + CloudSolid(), + Code(), + Collapse(), + Company(), + Compose(), + Computer(), + Copy(), + DarkMode(), + Delete(), + Devices(), + DialPad(), + Document(), + Download(), + DownloadIos(), + DragGrid(), + DragList(), + Earpiece(), + Edit(), + EditSolid(), + Email(), + EmailSolid(), + EndCall(), + Error(), + ErrorSolid(), + Expand(), + Explore(), + ExportArchive(), + Extensions(), + ExtensionsSolid(), + Favourite(), + FavouriteSolid(), + FileError(), + Files(), + Filter(), + Forward(), + Grid(), + Group(), + Guest(), + HeadphonesOffSolid(), + HeadphonesSolid(), + Help(), + HelpSolid(), + History(), + Home(), + HomeSolid(), + Host(), + Image(), + ImageError(), + IndentDecrease(), + IndentIncrease(), + Info(), + InfoSolid(), + InlineCode(), + Italic(), + Key(), + KeyOff(), + KeyOffSolid(), + KeySolid(), + Keyboard(), + Labs(), + Leave(), + Link(), + Linux(), + ListBulleted(), + ListNumbered(), + ListView(), + LocationNavigator(), + LocationNavigatorCentred(), + LocationPin(), + LocationPinSolid(), + Lock(), + LockOff(), + LockSolid(), + Mac(), + MarkAsRead(), + MarkAsUnread(), + MarkThreadsAsRead(), + MarkerReadReceipts(), + Mention(), + Menu(), + MicOff(), + MicOffSolid(), + MicOn(), + MicOnSolid(), + Minus(), + Mobile(), + Notifications(), + NotificationsOff(), + NotificationsOffSolid(), + NotificationsSolid(), + Offline(), + OverflowHorizontal(), + OverflowVertical(), + Pause(), + PauseSolid(), + Pin(), + PinSolid(), + Play(), + PlaySolid(), + Plus(), + Polls(), + PollsEnd(), + PopOut(), + Preferences(), + PresenceOutline8X8(), + PresenceSolid8X8(), + PresenceStrikethrough8X8(), + Public(), + QrCode(), + Quote(), + RaisedHandSolid(), + Reaction(), + ReactionAdd(), + ReactionSolid(), + Reply(), + Restart(), + Room(), + Search(), + Send(), + SendSolid(), + Settings(), + SettingsSolid(), + Share(), + ShareAndroid(), + ShareIos(), + ShareScreen(), + ShareScreenSolid(), + Shield(), + Sidebar(), + SignOut(), + Spinner(), + Spotlight(), + SpotlightView(), + Strikethrough(), + SwitchCameraSolid(), + TakePhoto(), + TakePhotoSolid(), + TextFormatting(), + Threads(), + ThreadsSolid(), + Time(), + Underline(), + Unknown(), + UnknownSolid(), + Unpin(), + User(), + UserAdd(), + UserAddSolid(), + UserProfile(), + UserProfileSolid(), + UserSolid(), + Verified(), + VideoCall(), + VideoCallDeclinedSolid(), + VideoCallMissedSolid(), + VideoCallOff(), + VideoCallOffSolid(), + VideoCallSolid(), + VisibilityOff(), + VisibilityOn(), + VoiceCall(), + VoiceCallSolid(), + VolumeOff(), + VolumeOffSolid(), + VolumeOn(), + VolumeOnSolid(), + Warning(), + WebBrowser(), + Windows(), + Workspace(), + WorkspaceSolid(), + ) + + val allResIds get() = persistentListOf( + R.drawable.ic_compound_admin, + R.drawable.ic_compound_arrow_down, + R.drawable.ic_compound_arrow_left, + R.drawable.ic_compound_arrow_right, + R.drawable.ic_compound_arrow_up, + R.drawable.ic_compound_arrow_up_right, + R.drawable.ic_compound_ask_to_join, + R.drawable.ic_compound_ask_to_join_solid, + R.drawable.ic_compound_attachment, + R.drawable.ic_compound_audio, + R.drawable.ic_compound_block, + R.drawable.ic_compound_bold, + R.drawable.ic_compound_calendar, + R.drawable.ic_compound_chart, + R.drawable.ic_compound_chat, + R.drawable.ic_compound_chat_new, + R.drawable.ic_compound_chat_problem, + R.drawable.ic_compound_chat_solid, + R.drawable.ic_compound_check, + R.drawable.ic_compound_check_circle, + R.drawable.ic_compound_check_circle_solid, + R.drawable.ic_compound_chevron_down, + R.drawable.ic_compound_chevron_left, + R.drawable.ic_compound_chevron_right, + R.drawable.ic_compound_chevron_up, + R.drawable.ic_compound_chevron_up_down, + R.drawable.ic_compound_circle, + R.drawable.ic_compound_close, + R.drawable.ic_compound_cloud, + R.drawable.ic_compound_cloud_solid, + R.drawable.ic_compound_code, + R.drawable.ic_compound_collapse, + R.drawable.ic_compound_company, + R.drawable.ic_compound_compose, + R.drawable.ic_compound_computer, + R.drawable.ic_compound_copy, + R.drawable.ic_compound_dark_mode, + R.drawable.ic_compound_delete, + R.drawable.ic_compound_devices, + R.drawable.ic_compound_dial_pad, + R.drawable.ic_compound_document, + R.drawable.ic_compound_download, + R.drawable.ic_compound_download_ios, + R.drawable.ic_compound_drag_grid, + R.drawable.ic_compound_drag_list, + R.drawable.ic_compound_earpiece, + R.drawable.ic_compound_edit, + R.drawable.ic_compound_edit_solid, + R.drawable.ic_compound_email, + R.drawable.ic_compound_email_solid, + R.drawable.ic_compound_end_call, + R.drawable.ic_compound_error, + R.drawable.ic_compound_error_solid, + R.drawable.ic_compound_expand, + R.drawable.ic_compound_explore, + R.drawable.ic_compound_export_archive, + R.drawable.ic_compound_extensions, + R.drawable.ic_compound_extensions_solid, + R.drawable.ic_compound_favourite, + R.drawable.ic_compound_favourite_solid, + R.drawable.ic_compound_file_error, + R.drawable.ic_compound_files, + R.drawable.ic_compound_filter, + R.drawable.ic_compound_forward, + R.drawable.ic_compound_grid, + R.drawable.ic_compound_group, + R.drawable.ic_compound_guest, + R.drawable.ic_compound_headphones_off_solid, + R.drawable.ic_compound_headphones_solid, + R.drawable.ic_compound_help, + R.drawable.ic_compound_help_solid, + R.drawable.ic_compound_history, + R.drawable.ic_compound_home, + R.drawable.ic_compound_home_solid, + R.drawable.ic_compound_host, + R.drawable.ic_compound_image, + R.drawable.ic_compound_image_error, + R.drawable.ic_compound_indent_decrease, + R.drawable.ic_compound_indent_increase, + R.drawable.ic_compound_info, + R.drawable.ic_compound_info_solid, + R.drawable.ic_compound_inline_code, + R.drawable.ic_compound_italic, + R.drawable.ic_compound_key, + R.drawable.ic_compound_key_off, + R.drawable.ic_compound_key_off_solid, + R.drawable.ic_compound_key_solid, + R.drawable.ic_compound_keyboard, + R.drawable.ic_compound_labs, + R.drawable.ic_compound_leave, + R.drawable.ic_compound_link, + R.drawable.ic_compound_linux, + R.drawable.ic_compound_list_bulleted, + R.drawable.ic_compound_list_numbered, + R.drawable.ic_compound_list_view, + R.drawable.ic_compound_location_navigator, + R.drawable.ic_compound_location_navigator_centred, + R.drawable.ic_compound_location_pin, + R.drawable.ic_compound_location_pin_solid, + R.drawable.ic_compound_lock, + R.drawable.ic_compound_lock_off, + R.drawable.ic_compound_lock_solid, + R.drawable.ic_compound_mac, + R.drawable.ic_compound_mark_as_read, + R.drawable.ic_compound_mark_as_unread, + R.drawable.ic_compound_mark_threads_as_read, + R.drawable.ic_compound_marker_read_receipts, + R.drawable.ic_compound_mention, + R.drawable.ic_compound_menu, + R.drawable.ic_compound_mic_off, + R.drawable.ic_compound_mic_off_solid, + R.drawable.ic_compound_mic_on, + R.drawable.ic_compound_mic_on_solid, + R.drawable.ic_compound_minus, + R.drawable.ic_compound_mobile, + R.drawable.ic_compound_notifications, + R.drawable.ic_compound_notifications_off, + R.drawable.ic_compound_notifications_off_solid, + R.drawable.ic_compound_notifications_solid, + R.drawable.ic_compound_offline, + R.drawable.ic_compound_overflow_horizontal, + R.drawable.ic_compound_overflow_vertical, + R.drawable.ic_compound_pause, + R.drawable.ic_compound_pause_solid, + R.drawable.ic_compound_pin, + R.drawable.ic_compound_pin_solid, + R.drawable.ic_compound_play, + R.drawable.ic_compound_play_solid, + R.drawable.ic_compound_plus, + R.drawable.ic_compound_polls, + R.drawable.ic_compound_polls_end, + R.drawable.ic_compound_pop_out, + R.drawable.ic_compound_preferences, + R.drawable.ic_compound_presence_outline_8_x_8, + R.drawable.ic_compound_presence_solid_8_x_8, + R.drawable.ic_compound_presence_strikethrough_8_x_8, + R.drawable.ic_compound_public, + R.drawable.ic_compound_qr_code, + R.drawable.ic_compound_quote, + R.drawable.ic_compound_raised_hand_solid, + R.drawable.ic_compound_reaction, + R.drawable.ic_compound_reaction_add, + R.drawable.ic_compound_reaction_solid, + R.drawable.ic_compound_reply, + R.drawable.ic_compound_restart, + R.drawable.ic_compound_room, + R.drawable.ic_compound_search, + R.drawable.ic_compound_send, + R.drawable.ic_compound_send_solid, + R.drawable.ic_compound_settings, + R.drawable.ic_compound_settings_solid, + R.drawable.ic_compound_share, + R.drawable.ic_compound_share_android, + R.drawable.ic_compound_share_ios, + R.drawable.ic_compound_share_screen, + R.drawable.ic_compound_share_screen_solid, + R.drawable.ic_compound_shield, + R.drawable.ic_compound_sidebar, + R.drawable.ic_compound_sign_out, + R.drawable.ic_compound_spinner, + R.drawable.ic_compound_spotlight, + R.drawable.ic_compound_spotlight_view, + R.drawable.ic_compound_strikethrough, + R.drawable.ic_compound_switch_camera_solid, + R.drawable.ic_compound_take_photo, + R.drawable.ic_compound_take_photo_solid, + R.drawable.ic_compound_text_formatting, + R.drawable.ic_compound_threads, + R.drawable.ic_compound_threads_solid, + R.drawable.ic_compound_time, + R.drawable.ic_compound_underline, + R.drawable.ic_compound_unknown, + R.drawable.ic_compound_unknown_solid, + R.drawable.ic_compound_unpin, + R.drawable.ic_compound_user, + R.drawable.ic_compound_user_add, + R.drawable.ic_compound_user_add_solid, + R.drawable.ic_compound_user_profile, + R.drawable.ic_compound_user_profile_solid, + R.drawable.ic_compound_user_solid, + R.drawable.ic_compound_verified, + R.drawable.ic_compound_video_call, + R.drawable.ic_compound_video_call_declined_solid, + R.drawable.ic_compound_video_call_missed_solid, + R.drawable.ic_compound_video_call_off, + R.drawable.ic_compound_video_call_off_solid, + R.drawable.ic_compound_video_call_solid, + R.drawable.ic_compound_visibility_off, + R.drawable.ic_compound_visibility_on, + R.drawable.ic_compound_voice_call, + R.drawable.ic_compound_voice_call_solid, + R.drawable.ic_compound_volume_off, + R.drawable.ic_compound_volume_off_solid, + R.drawable.ic_compound_volume_on, + R.drawable.ic_compound_volume_on_solid, + R.drawable.ic_compound_warning, + R.drawable.ic_compound_web_browser, + R.drawable.ic_compound_windows, + R.drawable.ic_compound_workspace, + R.drawable.ic_compound_workspace_solid, + ) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/DO_NOT_MODIFY.txt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/DO_NOT_MODIFY.txt new file mode 100644 index 0000000000..a6f7dd3f6a --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/DO_NOT_MODIFY.txt @@ -0,0 +1 @@ +Files inside this package are generated automatically from the Compound project (https://github.com/vector-im/compound-design-tokens) and will be batch-replaced when new tokens are generated. diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt new file mode 100644 index 0000000000..8da51213f8 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt @@ -0,0 +1,222 @@ +/* + * 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. + */ + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color + + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + + +/** + * This class holds all the semantic tokens of the Compound theme. + */ +@Immutable +data class SemanticColors( + /** Background colour for accent or brand actions. State: Hover */ + val bgAccentHovered: Color, + /** Background colour for accent or brand actions. State: Pressed */ + val bgAccentPressed: Color, + /** Background colour for accent or brand actions. State: Rest. */ + val bgAccentRest: Color, + /** Background colour for accent or brand actions. State: Selected */ + val bgAccentSelected: Color, + /** Background colour for primary actions. State: Disabled. */ + val bgActionPrimaryDisabled: Color, + /** Background colour for primary actions. State: Hover. */ + val bgActionPrimaryHovered: Color, + /** Background colour for primary actions. State: Pressed. */ + val bgActionPrimaryPressed: Color, + /** Background colour for primary actions. State: Rest. */ + val bgActionPrimaryRest: Color, + /** Background colour for secondary actions. State: Hover. */ + val bgActionSecondaryHovered: Color, + /** Background colour for secondary actions. State: Pressed. */ + val bgActionSecondaryPressed: Color, + /** Background colour for secondary actions. State: Rest. */ + val bgActionSecondaryRest: Color, + /** Badge accent background colour */ + val bgBadgeAccent: Color, + /** Badge default background colour */ + val bgBadgeDefault: Color, + /** Badge info background colour */ + val bgBadgeInfo: Color, + /** Default global background for the user interface. +Elevation: Default (Level 0) */ + val bgCanvasDefault: Color, + /** Default global background for the user interface. +Elevation: Level 1. */ + val bgCanvasDefaultLevel1: Color, + /** Default background for disabled elements. There's no minimum contrast requirement. */ + val bgCanvasDisabled: Color, + /** High-contrast background color for critical state. State: Hover. */ + val bgCriticalHovered: Color, + /** High-contrast background color for critical state. State: Rest. */ + val bgCriticalPrimary: Color, + /** Default subtle critical surfaces. State: Rest. */ + val bgCriticalSubtle: Color, + /** Default subtle critical surfaces. State: Hover. */ + val bgCriticalSubtleHovered: Color, + /** Decorative background (1, Lime) for avatars and usernames. */ + val bgDecorative1: Color, + /** Decorative background (2, Cyan) for avatars and usernames. */ + val bgDecorative2: Color, + /** Decorative background (3, Fuchsia) for avatars and usernames. */ + val bgDecorative3: Color, + /** Decorative background (4, Purple) for avatars and usernames. */ + val bgDecorative4: Color, + /** Decorative background (5, Pink) for avatars and usernames. */ + val bgDecorative5: Color, + /** Decorative background (6, Orange) for avatars and usernames. */ + val bgDecorative6: Color, + /** Subtle background colour for informational elements. State: Rest. */ + val bgInfoSubtle: Color, + /** Medium contrast surfaces. +Elevation: Default (Level 2). */ + val bgSubtlePrimary: Color, + /** Low contrast surfaces. +Elevation: Default (Level 1). */ + val bgSubtleSecondary: Color, + /** Lower contrast surfaces. +Elevation: Level 0. */ + val bgSubtleSecondaryLevel0: Color, + /** Subtle background colour for success state elements. State: Rest. */ + val bgSuccessSubtle: Color, + /** accent border intended for keylines on message highlights */ + val borderAccentSubtle: Color, + /** High-contrast border for critical state. State: Hover. */ + val borderCriticalHovered: Color, + /** High-contrast border for critical state. State: Rest. */ + val borderCriticalPrimary: Color, + /** Subtle border colour for critical state elements. */ + val borderCriticalSubtle: Color, + /** Used for borders of disabled elements. There's no minimum contrast requirement. */ + val borderDisabled: Color, + /** Used for the focus state outline. */ + val borderFocused: Color, + /** Subtle border colour for informational elements. */ + val borderInfoSubtle: Color, + /** Default contrast for accessible interactive element borders. State: Hover. */ + val borderInteractiveHovered: Color, + /** Default contrast for accessible interactive element borders. State: Rest. */ + val borderInteractivePrimary: Color, + /** ⚠️ Lowest contrast for non-accessible interactive element borders, <3:1. Only use for non-essential borders. Do not rely exclusively on them. State: Rest. */ + val borderInteractiveSecondary: Color, + /** Subtle border colour for success state elements. */ + val borderSuccessSubtle: Color, + /** Background gradient stop for super and send buttons */ + val gradientActionStop1: Color, + /** Background gradient stop for super and send buttons */ + val gradientActionStop2: Color, + /** Background gradient stop for super and send buttons */ + val gradientActionStop3: Color, + /** Background gradient stop for super and send buttons */ + val gradientActionStop4: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop1: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop2: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop3: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop4: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop5: Color, + /** Subtle background gradient stop for info */ + val gradientInfoStop6: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop1: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop2: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop3: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop4: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop5: Color, + /** Subtle background gradient stop for message highlight and bloom */ + val gradientSubtleStop6: Color, + /** Highest contrast accessible accent icons. */ + val iconAccentPrimary: Color, + /** Lowest contrast accessible accent icons. */ + val iconAccentTertiary: Color, + /** High-contrast icon for critical state. State: Rest. */ + val iconCriticalPrimary: Color, + /** Use for icons in disabled elements. There's no minimum contrast requirement. */ + val iconDisabled: Color, + /** High-contrast icon for informational elements. */ + val iconInfoPrimary: Color, + /** Highest contrast icon color on top of high-contrast solid backgrounds like primary, accent, or destructive actions. */ + val iconOnSolidPrimary: Color, + /** Highest contrast icons. */ + val iconPrimary: Color, + /** Translucent version of primary icon. Refer to it for intended use. */ + val iconPrimaryAlpha: Color, + /** ⚠️ Lowest contrast non-accessible icons, <3:1. Only use for non-essential icons. Do not rely exclusively on them. */ + val iconQuaternary: Color, + /** Translucent version of quaternary icon. Refer to it for intended use. */ + val iconQuaternaryAlpha: Color, + /** Lower contrast icons. */ + val iconSecondary: Color, + /** Translucent version of secondary icon. Refer to it for intended use. */ + val iconSecondaryAlpha: Color, + /** High-contrast icon for success state elements. */ + val iconSuccessPrimary: Color, + /** Lowest contrast accessible icons. */ + val iconTertiary: Color, + /** Translucent version of tertiary icon. Refer to it for intended use. */ + val iconTertiaryAlpha: Color, + /** Accent text colour for plain actions. */ + val textActionAccent: Color, + /** Default text colour for plain actions. */ + val textActionPrimary: Color, + /** Badge accent text colour */ + val textBadgeAccent: Color, + /** Badge info text colour */ + val textBadgeInfo: Color, + /** Text colour for destructive plain actions. */ + val textCriticalPrimary: Color, + /** Decorative text colour (1, Lime) for avatars and usernames. */ + val textDecorative1: Color, + /** Decorative text colour (2, Cyan) for avatars and usernames. */ + val textDecorative2: Color, + /** Decorative text colour (3, Fuchsia) for avatars and usernames. */ + val textDecorative3: Color, + /** Decorative text colour (4, Purple) for avatars and usernames. */ + val textDecorative4: Color, + /** Decorative text colour (5, Pink) for avatars and usernames. */ + val textDecorative5: Color, + /** Decorative text colour (6, Orange) for avatars and usernames. */ + val textDecorative6: Color, + /** Use for regular text in disabled elements. There's no minimum contrast requirement. */ + val textDisabled: Color, + /** Accent text colour for informational elements. */ + val textInfoPrimary: Color, + /** Text colour for external links. */ + val textLinkExternal: Color, + /** For use as text color on top of high-contrast solid backgrounds like primary, accent, or destructive actions. */ + val textOnSolidPrimary: Color, + /** Highest contrast text. */ + val textPrimary: Color, + /** Lowest contrast text. */ + val textSecondary: Color, + /** Accent text colour for success state elements. */ + val textSuccessPrimary: Color, + /** True for light theme, false for dark theme. */ + val isLight: Boolean, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDark.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDark.kt new file mode 100644 index 0000000000..5ccdfaa308 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDark.kt @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.internal.DarkColorTokens + +/** + * Semantic colors for the dark Compound theme. + */ +@OptIn(CoreColorToken::class) +val compoundColorsDark = SemanticColors( + bgAccentHovered = DarkColorTokens.colorGreen1000, + bgAccentPressed = DarkColorTokens.colorGreen1100, + bgAccentRest = DarkColorTokens.colorGreen900, + bgAccentSelected = DarkColorTokens.colorAlphaGreen300, + bgActionPrimaryDisabled = DarkColorTokens.colorGray700, + bgActionPrimaryHovered = DarkColorTokens.colorGray1200, + bgActionPrimaryPressed = DarkColorTokens.colorGray1100, + bgActionPrimaryRest = DarkColorTokens.colorGray1400, + bgActionSecondaryHovered = DarkColorTokens.colorAlphaGray200, + bgActionSecondaryPressed = DarkColorTokens.colorAlphaGray300, + bgActionSecondaryRest = DarkColorTokens.colorThemeBg, + bgBadgeAccent = DarkColorTokens.colorAlphaGreen300, + bgBadgeDefault = DarkColorTokens.colorAlphaGray300, + bgBadgeInfo = DarkColorTokens.colorAlphaBlue300, + bgCanvasDefault = DarkColorTokens.colorThemeBg, + bgCanvasDefaultLevel1 = DarkColorTokens.colorGray300, + bgCanvasDisabled = DarkColorTokens.colorGray200, + bgCriticalHovered = DarkColorTokens.colorRed1000, + bgCriticalPrimary = DarkColorTokens.colorRed900, + bgCriticalSubtle = DarkColorTokens.colorRed200, + bgCriticalSubtleHovered = DarkColorTokens.colorRed300, + bgDecorative1 = DarkColorTokens.colorLime300, + bgDecorative2 = DarkColorTokens.colorCyan300, + bgDecorative3 = DarkColorTokens.colorFuchsia300, + bgDecorative4 = DarkColorTokens.colorPurple300, + bgDecorative5 = DarkColorTokens.colorPink300, + bgDecorative6 = DarkColorTokens.colorOrange300, + bgInfoSubtle = DarkColorTokens.colorBlue200, + bgSubtlePrimary = DarkColorTokens.colorGray400, + bgSubtleSecondary = DarkColorTokens.colorGray300, + bgSubtleSecondaryLevel0 = DarkColorTokens.colorThemeBg, + bgSuccessSubtle = DarkColorTokens.colorGreen200, + borderAccentSubtle = DarkColorTokens.colorGreen700, + borderCriticalHovered = DarkColorTokens.colorRed1000, + borderCriticalPrimary = DarkColorTokens.colorRed900, + borderCriticalSubtle = DarkColorTokens.colorRed500, + borderDisabled = DarkColorTokens.colorGray500, + borderFocused = DarkColorTokens.colorBlue900, + borderInfoSubtle = DarkColorTokens.colorBlue700, + borderInteractiveHovered = DarkColorTokens.colorGray1100, + borderInteractivePrimary = DarkColorTokens.colorGray800, + borderInteractiveSecondary = DarkColorTokens.colorGray600, + borderSuccessSubtle = DarkColorTokens.colorGreen500, + gradientActionStop1 = DarkColorTokens.colorGreen1100, + gradientActionStop2 = DarkColorTokens.colorGreen900, + gradientActionStop3 = DarkColorTokens.colorGreen700, + gradientActionStop4 = DarkColorTokens.colorGreen500, + gradientInfoStop1 = DarkColorTokens.colorAlphaBlue500, + gradientInfoStop2 = DarkColorTokens.colorAlphaBlue400, + gradientInfoStop3 = DarkColorTokens.colorAlphaBlue300, + gradientInfoStop4 = DarkColorTokens.colorAlphaBlue200, + gradientInfoStop5 = DarkColorTokens.colorAlphaBlue100, + gradientInfoStop6 = DarkColorTokens.colorTransparent, + gradientSubtleStop1 = DarkColorTokens.colorAlphaGreen500, + gradientSubtleStop2 = DarkColorTokens.colorAlphaGreen400, + gradientSubtleStop3 = DarkColorTokens.colorAlphaGreen300, + gradientSubtleStop4 = DarkColorTokens.colorAlphaGreen200, + gradientSubtleStop5 = DarkColorTokens.colorAlphaGreen100, + gradientSubtleStop6 = DarkColorTokens.colorTransparent, + iconAccentPrimary = DarkColorTokens.colorGreen900, + iconAccentTertiary = DarkColorTokens.colorGreen800, + iconCriticalPrimary = DarkColorTokens.colorRed900, + iconDisabled = DarkColorTokens.colorGray700, + iconInfoPrimary = DarkColorTokens.colorBlue900, + iconOnSolidPrimary = DarkColorTokens.colorThemeBg, + iconPrimary = DarkColorTokens.colorGray1400, + iconPrimaryAlpha = DarkColorTokens.colorAlphaGray1400, + iconQuaternary = DarkColorTokens.colorGray700, + iconQuaternaryAlpha = DarkColorTokens.colorAlphaGray700, + iconSecondary = DarkColorTokens.colorGray900, + iconSecondaryAlpha = DarkColorTokens.colorAlphaGray900, + iconSuccessPrimary = DarkColorTokens.colorGreen900, + iconTertiary = DarkColorTokens.colorGray800, + iconTertiaryAlpha = DarkColorTokens.colorAlphaGray800, + textActionAccent = DarkColorTokens.colorGreen900, + textActionPrimary = DarkColorTokens.colorGray1400, + textBadgeAccent = DarkColorTokens.colorGreen1100, + textBadgeInfo = DarkColorTokens.colorBlue1100, + textCriticalPrimary = DarkColorTokens.colorRed900, + textDecorative1 = DarkColorTokens.colorLime1100, + textDecorative2 = DarkColorTokens.colorCyan1100, + textDecorative3 = DarkColorTokens.colorFuchsia1100, + textDecorative4 = DarkColorTokens.colorPurple1100, + textDecorative5 = DarkColorTokens.colorPink1100, + textDecorative6 = DarkColorTokens.colorOrange1100, + textDisabled = DarkColorTokens.colorGray800, + textInfoPrimary = DarkColorTokens.colorBlue900, + textLinkExternal = DarkColorTokens.colorBlue900, + textOnSolidPrimary = DarkColorTokens.colorThemeBg, + textPrimary = DarkColorTokens.colorGray1400, + textSecondary = DarkColorTokens.colorGray900, + textSuccessPrimary = DarkColorTokens.colorGreen900, + isLight = false, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDarkHc.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDarkHc.kt new file mode 100644 index 0000000000..88d2ef3abe --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsDarkHc.kt @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.internal.DarkHcColorTokens + +/** + * Semantic colors for the high contrast dark Compound theme. + */ +@OptIn(CoreColorToken::class) +val compoundColorsHcDark = SemanticColors( + bgAccentHovered = DarkHcColorTokens.colorGreen1000, + bgAccentPressed = DarkHcColorTokens.colorGreen1100, + bgAccentRest = DarkHcColorTokens.colorGreen900, + bgAccentSelected = DarkHcColorTokens.colorAlphaGreen300, + bgActionPrimaryDisabled = DarkHcColorTokens.colorGray700, + bgActionPrimaryHovered = DarkHcColorTokens.colorGray1200, + bgActionPrimaryPressed = DarkHcColorTokens.colorGray1100, + bgActionPrimaryRest = DarkHcColorTokens.colorGray1400, + bgActionSecondaryHovered = DarkHcColorTokens.colorAlphaGray200, + bgActionSecondaryPressed = DarkHcColorTokens.colorAlphaGray300, + bgActionSecondaryRest = DarkHcColorTokens.colorThemeBg, + bgBadgeAccent = DarkHcColorTokens.colorAlphaGreen300, + bgBadgeDefault = DarkHcColorTokens.colorAlphaGray300, + bgBadgeInfo = DarkHcColorTokens.colorAlphaBlue300, + bgCanvasDefault = DarkHcColorTokens.colorThemeBg, + bgCanvasDefaultLevel1 = DarkHcColorTokens.colorGray300, + bgCanvasDisabled = DarkHcColorTokens.colorGray200, + bgCriticalHovered = DarkHcColorTokens.colorRed1000, + bgCriticalPrimary = DarkHcColorTokens.colorRed900, + bgCriticalSubtle = DarkHcColorTokens.colorRed200, + bgCriticalSubtleHovered = DarkHcColorTokens.colorRed300, + bgDecorative1 = DarkHcColorTokens.colorLime300, + bgDecorative2 = DarkHcColorTokens.colorCyan300, + bgDecorative3 = DarkHcColorTokens.colorFuchsia300, + bgDecorative4 = DarkHcColorTokens.colorPurple300, + bgDecorative5 = DarkHcColorTokens.colorPink300, + bgDecorative6 = DarkHcColorTokens.colorOrange300, + bgInfoSubtle = DarkHcColorTokens.colorBlue200, + bgSubtlePrimary = DarkHcColorTokens.colorGray400, + bgSubtleSecondary = DarkHcColorTokens.colorGray300, + bgSubtleSecondaryLevel0 = DarkHcColorTokens.colorThemeBg, + bgSuccessSubtle = DarkHcColorTokens.colorGreen200, + borderAccentSubtle = DarkHcColorTokens.colorGreen700, + borderCriticalHovered = DarkHcColorTokens.colorRed1000, + borderCriticalPrimary = DarkHcColorTokens.colorRed900, + borderCriticalSubtle = DarkHcColorTokens.colorRed500, + borderDisabled = DarkHcColorTokens.colorGray500, + borderFocused = DarkHcColorTokens.colorBlue900, + borderInfoSubtle = DarkHcColorTokens.colorBlue700, + borderInteractiveHovered = DarkHcColorTokens.colorGray1100, + borderInteractivePrimary = DarkHcColorTokens.colorGray800, + borderInteractiveSecondary = DarkHcColorTokens.colorGray600, + borderSuccessSubtle = DarkHcColorTokens.colorGreen500, + gradientActionStop1 = DarkHcColorTokens.colorGreen1100, + gradientActionStop2 = DarkHcColorTokens.colorGreen900, + gradientActionStop3 = DarkHcColorTokens.colorGreen700, + gradientActionStop4 = DarkHcColorTokens.colorGreen500, + gradientInfoStop1 = DarkHcColorTokens.colorAlphaBlue500, + gradientInfoStop2 = DarkHcColorTokens.colorAlphaBlue400, + gradientInfoStop3 = DarkHcColorTokens.colorAlphaBlue300, + gradientInfoStop4 = DarkHcColorTokens.colorAlphaBlue200, + gradientInfoStop5 = DarkHcColorTokens.colorAlphaBlue100, + gradientInfoStop6 = DarkHcColorTokens.colorTransparent, + gradientSubtleStop1 = DarkHcColorTokens.colorAlphaGreen500, + gradientSubtleStop2 = DarkHcColorTokens.colorAlphaGreen400, + gradientSubtleStop3 = DarkHcColorTokens.colorAlphaGreen300, + gradientSubtleStop4 = DarkHcColorTokens.colorAlphaGreen200, + gradientSubtleStop5 = DarkHcColorTokens.colorAlphaGreen100, + gradientSubtleStop6 = DarkHcColorTokens.colorTransparent, + iconAccentPrimary = DarkHcColorTokens.colorGreen900, + iconAccentTertiary = DarkHcColorTokens.colorGreen800, + iconCriticalPrimary = DarkHcColorTokens.colorRed900, + iconDisabled = DarkHcColorTokens.colorGray700, + iconInfoPrimary = DarkHcColorTokens.colorBlue900, + iconOnSolidPrimary = DarkHcColorTokens.colorThemeBg, + iconPrimary = DarkHcColorTokens.colorGray1400, + iconPrimaryAlpha = DarkHcColorTokens.colorAlphaGray1400, + iconQuaternary = DarkHcColorTokens.colorGray700, + iconQuaternaryAlpha = DarkHcColorTokens.colorAlphaGray700, + iconSecondary = DarkHcColorTokens.colorGray900, + iconSecondaryAlpha = DarkHcColorTokens.colorAlphaGray900, + iconSuccessPrimary = DarkHcColorTokens.colorGreen900, + iconTertiary = DarkHcColorTokens.colorGray800, + iconTertiaryAlpha = DarkHcColorTokens.colorAlphaGray800, + textActionAccent = DarkHcColorTokens.colorGreen900, + textActionPrimary = DarkHcColorTokens.colorGray1400, + textBadgeAccent = DarkHcColorTokens.colorGreen1100, + textBadgeInfo = DarkHcColorTokens.colorBlue1100, + textCriticalPrimary = DarkHcColorTokens.colorRed900, + textDecorative1 = DarkHcColorTokens.colorLime1100, + textDecorative2 = DarkHcColorTokens.colorCyan1100, + textDecorative3 = DarkHcColorTokens.colorFuchsia1100, + textDecorative4 = DarkHcColorTokens.colorPurple1100, + textDecorative5 = DarkHcColorTokens.colorPink1100, + textDecorative6 = DarkHcColorTokens.colorOrange1100, + textDisabled = DarkHcColorTokens.colorGray800, + textInfoPrimary = DarkHcColorTokens.colorBlue900, + textLinkExternal = DarkHcColorTokens.colorBlue900, + textOnSolidPrimary = DarkHcColorTokens.colorThemeBg, + textPrimary = DarkHcColorTokens.colorGray1400, + textSecondary = DarkHcColorTokens.colorGray900, + textSuccessPrimary = DarkHcColorTokens.colorGreen900, + isLight = false, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLight.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLight.kt new file mode 100644 index 0000000000..03173ad24e --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLight.kt @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.internal.LightColorTokens + +/** + * Semantic colors for the light Compound theme. + */ +@OptIn(CoreColorToken::class) +val compoundColorsLight = SemanticColors( + bgAccentHovered = LightColorTokens.colorGreen1000, + bgAccentPressed = LightColorTokens.colorGreen1100, + bgAccentRest = LightColorTokens.colorGreen900, + bgAccentSelected = LightColorTokens.colorAlphaGreen300, + bgActionPrimaryDisabled = LightColorTokens.colorGray700, + bgActionPrimaryHovered = LightColorTokens.colorGray1200, + bgActionPrimaryPressed = LightColorTokens.colorGray1100, + bgActionPrimaryRest = LightColorTokens.colorGray1400, + bgActionSecondaryHovered = LightColorTokens.colorAlphaGray200, + bgActionSecondaryPressed = LightColorTokens.colorAlphaGray300, + bgActionSecondaryRest = LightColorTokens.colorThemeBg, + bgBadgeAccent = LightColorTokens.colorAlphaGreen300, + bgBadgeDefault = LightColorTokens.colorAlphaGray300, + bgBadgeInfo = LightColorTokens.colorAlphaBlue300, + bgCanvasDefault = LightColorTokens.colorThemeBg, + bgCanvasDefaultLevel1 = LightColorTokens.colorThemeBg, + bgCanvasDisabled = LightColorTokens.colorGray200, + bgCriticalHovered = LightColorTokens.colorRed1000, + bgCriticalPrimary = LightColorTokens.colorRed900, + bgCriticalSubtle = LightColorTokens.colorRed200, + bgCriticalSubtleHovered = LightColorTokens.colorRed300, + bgDecorative1 = LightColorTokens.colorLime300, + bgDecorative2 = LightColorTokens.colorCyan300, + bgDecorative3 = LightColorTokens.colorFuchsia300, + bgDecorative4 = LightColorTokens.colorPurple300, + bgDecorative5 = LightColorTokens.colorPink300, + bgDecorative6 = LightColorTokens.colorOrange300, + bgInfoSubtle = LightColorTokens.colorBlue200, + bgSubtlePrimary = LightColorTokens.colorGray400, + bgSubtleSecondary = LightColorTokens.colorGray300, + bgSubtleSecondaryLevel0 = LightColorTokens.colorGray300, + bgSuccessSubtle = LightColorTokens.colorGreen200, + borderAccentSubtle = LightColorTokens.colorGreen700, + borderCriticalHovered = LightColorTokens.colorRed1000, + borderCriticalPrimary = LightColorTokens.colorRed900, + borderCriticalSubtle = LightColorTokens.colorRed500, + borderDisabled = LightColorTokens.colorGray500, + borderFocused = LightColorTokens.colorBlue900, + borderInfoSubtle = LightColorTokens.colorBlue700, + borderInteractiveHovered = LightColorTokens.colorGray1100, + borderInteractivePrimary = LightColorTokens.colorGray800, + borderInteractiveSecondary = LightColorTokens.colorGray600, + borderSuccessSubtle = LightColorTokens.colorGreen500, + gradientActionStop1 = LightColorTokens.colorGreen500, + gradientActionStop2 = LightColorTokens.colorGreen700, + gradientActionStop3 = LightColorTokens.colorGreen900, + gradientActionStop4 = LightColorTokens.colorGreen1100, + gradientInfoStop1 = LightColorTokens.colorAlphaBlue500, + gradientInfoStop2 = LightColorTokens.colorAlphaBlue400, + gradientInfoStop3 = LightColorTokens.colorAlphaBlue300, + gradientInfoStop4 = LightColorTokens.colorAlphaBlue200, + gradientInfoStop5 = LightColorTokens.colorAlphaBlue100, + gradientInfoStop6 = LightColorTokens.colorTransparent, + gradientSubtleStop1 = LightColorTokens.colorAlphaGreen500, + gradientSubtleStop2 = LightColorTokens.colorAlphaGreen400, + gradientSubtleStop3 = LightColorTokens.colorAlphaGreen300, + gradientSubtleStop4 = LightColorTokens.colorAlphaGreen200, + gradientSubtleStop5 = LightColorTokens.colorAlphaGreen100, + gradientSubtleStop6 = LightColorTokens.colorTransparent, + iconAccentPrimary = LightColorTokens.colorGreen900, + iconAccentTertiary = LightColorTokens.colorGreen800, + iconCriticalPrimary = LightColorTokens.colorRed900, + iconDisabled = LightColorTokens.colorGray700, + iconInfoPrimary = LightColorTokens.colorBlue900, + iconOnSolidPrimary = LightColorTokens.colorThemeBg, + iconPrimary = LightColorTokens.colorGray1400, + iconPrimaryAlpha = LightColorTokens.colorAlphaGray1400, + iconQuaternary = LightColorTokens.colorGray700, + iconQuaternaryAlpha = LightColorTokens.colorAlphaGray700, + iconSecondary = LightColorTokens.colorGray900, + iconSecondaryAlpha = LightColorTokens.colorAlphaGray900, + iconSuccessPrimary = LightColorTokens.colorGreen900, + iconTertiary = LightColorTokens.colorGray800, + iconTertiaryAlpha = LightColorTokens.colorAlphaGray800, + textActionAccent = LightColorTokens.colorGreen900, + textActionPrimary = LightColorTokens.colorGray1400, + textBadgeAccent = LightColorTokens.colorGreen1100, + textBadgeInfo = LightColorTokens.colorBlue1100, + textCriticalPrimary = LightColorTokens.colorRed900, + textDecorative1 = LightColorTokens.colorLime1100, + textDecorative2 = LightColorTokens.colorCyan1100, + textDecorative3 = LightColorTokens.colorFuchsia1100, + textDecorative4 = LightColorTokens.colorPurple1100, + textDecorative5 = LightColorTokens.colorPink1100, + textDecorative6 = LightColorTokens.colorOrange1100, + textDisabled = LightColorTokens.colorGray800, + textInfoPrimary = LightColorTokens.colorBlue900, + textLinkExternal = LightColorTokens.colorBlue900, + textOnSolidPrimary = LightColorTokens.colorThemeBg, + textPrimary = LightColorTokens.colorGray1400, + textSecondary = LightColorTokens.colorGray900, + textSuccessPrimary = LightColorTokens.colorGreen900, + isLight = true, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLightHc.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLightHc.kt new file mode 100644 index 0000000000..00100f7ea8 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColorsLightHc.kt @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import io.element.android.compound.annotations.CoreColorToken +import io.element.android.compound.tokens.generated.internal.LightHcColorTokens + +/** + * Semantic colors for the high contrast light Compound theme. + */ +@OptIn(CoreColorToken::class) +val compoundColorsHcLight = SemanticColors( + bgAccentHovered = LightHcColorTokens.colorGreen1000, + bgAccentPressed = LightHcColorTokens.colorGreen1100, + bgAccentRest = LightHcColorTokens.colorGreen900, + bgAccentSelected = LightHcColorTokens.colorAlphaGreen300, + bgActionPrimaryDisabled = LightHcColorTokens.colorGray700, + bgActionPrimaryHovered = LightHcColorTokens.colorGray1200, + bgActionPrimaryPressed = LightHcColorTokens.colorGray1100, + bgActionPrimaryRest = LightHcColorTokens.colorGray1400, + bgActionSecondaryHovered = LightHcColorTokens.colorAlphaGray200, + bgActionSecondaryPressed = LightHcColorTokens.colorAlphaGray300, + bgActionSecondaryRest = LightHcColorTokens.colorThemeBg, + bgBadgeAccent = LightHcColorTokens.colorAlphaGreen300, + bgBadgeDefault = LightHcColorTokens.colorAlphaGray300, + bgBadgeInfo = LightHcColorTokens.colorAlphaBlue300, + bgCanvasDefault = LightHcColorTokens.colorThemeBg, + bgCanvasDefaultLevel1 = LightHcColorTokens.colorThemeBg, + bgCanvasDisabled = LightHcColorTokens.colorGray200, + bgCriticalHovered = LightHcColorTokens.colorRed1000, + bgCriticalPrimary = LightHcColorTokens.colorRed900, + bgCriticalSubtle = LightHcColorTokens.colorRed200, + bgCriticalSubtleHovered = LightHcColorTokens.colorRed300, + bgDecorative1 = LightHcColorTokens.colorLime300, + bgDecorative2 = LightHcColorTokens.colorCyan300, + bgDecorative3 = LightHcColorTokens.colorFuchsia300, + bgDecorative4 = LightHcColorTokens.colorPurple300, + bgDecorative5 = LightHcColorTokens.colorPink300, + bgDecorative6 = LightHcColorTokens.colorOrange300, + bgInfoSubtle = LightHcColorTokens.colorBlue200, + bgSubtlePrimary = LightHcColorTokens.colorGray400, + bgSubtleSecondary = LightHcColorTokens.colorGray300, + bgSubtleSecondaryLevel0 = LightHcColorTokens.colorGray300, + bgSuccessSubtle = LightHcColorTokens.colorGreen200, + borderAccentSubtle = LightHcColorTokens.colorGreen700, + borderCriticalHovered = LightHcColorTokens.colorRed1000, + borderCriticalPrimary = LightHcColorTokens.colorRed900, + borderCriticalSubtle = LightHcColorTokens.colorRed500, + borderDisabled = LightHcColorTokens.colorGray500, + borderFocused = LightHcColorTokens.colorBlue900, + borderInfoSubtle = LightHcColorTokens.colorBlue700, + borderInteractiveHovered = LightHcColorTokens.colorGray1100, + borderInteractivePrimary = LightHcColorTokens.colorGray800, + borderInteractiveSecondary = LightHcColorTokens.colorGray600, + borderSuccessSubtle = LightHcColorTokens.colorGreen500, + gradientActionStop1 = LightHcColorTokens.colorGreen500, + gradientActionStop2 = LightHcColorTokens.colorGreen700, + gradientActionStop3 = LightHcColorTokens.colorGreen900, + gradientActionStop4 = LightHcColorTokens.colorGreen1100, + gradientInfoStop1 = LightHcColorTokens.colorAlphaBlue500, + gradientInfoStop2 = LightHcColorTokens.colorAlphaBlue400, + gradientInfoStop3 = LightHcColorTokens.colorAlphaBlue300, + gradientInfoStop4 = LightHcColorTokens.colorAlphaBlue200, + gradientInfoStop5 = LightHcColorTokens.colorAlphaBlue100, + gradientInfoStop6 = LightHcColorTokens.colorTransparent, + gradientSubtleStop1 = LightHcColorTokens.colorAlphaGreen500, + gradientSubtleStop2 = LightHcColorTokens.colorAlphaGreen400, + gradientSubtleStop3 = LightHcColorTokens.colorAlphaGreen300, + gradientSubtleStop4 = LightHcColorTokens.colorAlphaGreen200, + gradientSubtleStop5 = LightHcColorTokens.colorAlphaGreen100, + gradientSubtleStop6 = LightHcColorTokens.colorTransparent, + iconAccentPrimary = LightHcColorTokens.colorGreen900, + iconAccentTertiary = LightHcColorTokens.colorGreen800, + iconCriticalPrimary = LightHcColorTokens.colorRed900, + iconDisabled = LightHcColorTokens.colorGray700, + iconInfoPrimary = LightHcColorTokens.colorBlue900, + iconOnSolidPrimary = LightHcColorTokens.colorThemeBg, + iconPrimary = LightHcColorTokens.colorGray1400, + iconPrimaryAlpha = LightHcColorTokens.colorAlphaGray1400, + iconQuaternary = LightHcColorTokens.colorGray700, + iconQuaternaryAlpha = LightHcColorTokens.colorAlphaGray700, + iconSecondary = LightHcColorTokens.colorGray900, + iconSecondaryAlpha = LightHcColorTokens.colorAlphaGray900, + iconSuccessPrimary = LightHcColorTokens.colorGreen900, + iconTertiary = LightHcColorTokens.colorGray800, + iconTertiaryAlpha = LightHcColorTokens.colorAlphaGray800, + textActionAccent = LightHcColorTokens.colorGreen900, + textActionPrimary = LightHcColorTokens.colorGray1400, + textBadgeAccent = LightHcColorTokens.colorGreen1100, + textBadgeInfo = LightHcColorTokens.colorBlue1100, + textCriticalPrimary = LightHcColorTokens.colorRed900, + textDecorative1 = LightHcColorTokens.colorLime1100, + textDecorative2 = LightHcColorTokens.colorCyan1100, + textDecorative3 = LightHcColorTokens.colorFuchsia1100, + textDecorative4 = LightHcColorTokens.colorPurple1100, + textDecorative5 = LightHcColorTokens.colorPink1100, + textDecorative6 = LightHcColorTokens.colorOrange1100, + textDisabled = LightHcColorTokens.colorGray800, + textInfoPrimary = LightHcColorTokens.colorBlue900, + textLinkExternal = LightHcColorTokens.colorBlue900, + textOnSolidPrimary = LightHcColorTokens.colorThemeBg, + textPrimary = LightHcColorTokens.colorGray1400, + textSecondary = LightHcColorTokens.colorGray900, + textSuccessPrimary = LightHcColorTokens.colorGreen900, + isLight = true, +) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt new file mode 100644 index 0000000000..a25b79234c --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt @@ -0,0 +1,174 @@ +/* + * 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. + */ + + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated + +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.em +import androidx.compose.ui.unit.sp +import androidx.compose.ui.text.PlatformTextStyle +import androidx.compose.ui.text.style.LineHeightStyle + +object TypographyTokens { + val fontBodyLgMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + lineHeight = 22.sp, + fontSize = 16.sp, + letterSpacing = 0.015625.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodyLgRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 22.sp, + fontSize = 16.sp, + letterSpacing = 0.015625.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodyMdMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + lineHeight = 20.sp, + fontSize = 14.sp, + letterSpacing = 0.017857.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodyMdRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 20.sp, + fontSize = 14.sp, + letterSpacing = 0.017857.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodySmMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + lineHeight = 17.sp, + fontSize = 12.sp, + letterSpacing = 0.033333.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodySmRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 17.sp, + fontSize = 12.sp, + letterSpacing = 0.033333.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodyXsMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + lineHeight = 15.sp, + fontSize = 11.sp, + letterSpacing = 0.045454.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontBodyXsRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 15.sp, + fontSize = 11.sp, + letterSpacing = 0.045454.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingLgBold = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W700, + lineHeight = 34.sp, + fontSize = 28.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingLgRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 34.sp, + fontSize = 28.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingMdBold = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W700, + lineHeight = 27.sp, + fontSize = 22.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingMdRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 27.sp, + fontSize = 22.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingSmMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + lineHeight = 25.sp, + fontSize = 20.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingSmRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 25.sp, + fontSize = 20.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingXlBold = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W700, + lineHeight = 41.sp, + fontSize = 34.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) + val fontHeadingXlRegular = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W400, + lineHeight = 41.sp, + fontSize = 34.sp, + letterSpacing = 0.em, + platformStyle = PlatformTextStyle(includeFontPadding = false), + lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) + ) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt new file mode 100644 index 0000000000..1272c0df16 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt @@ -0,0 +1,335 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated.internal + +import androidx.compose.ui.graphics.Color +import io.element.android.compound.annotations.CoreColorToken + +@CoreColorToken +object DarkColorTokens { + val colorAlphaBlue100 = Color(0xff00055c) + val colorAlphaBlue1000 = Color(0xf062a0fe) + val colorAlphaBlue1100 = Color(0xf57cb2fd) + val colorAlphaBlue1200 = Color(0xf7a3c8ff) + val colorAlphaBlue1300 = Color(0xfccde1fe) + val colorAlphaBlue1400 = Color(0xffe6effe) + val colorAlphaBlue200 = Color(0xff00095c) + val colorAlphaBlue300 = Color(0xff001366) + val colorAlphaBlue400 = Color(0xff001e70) + val colorAlphaBlue500 = Color(0xa1003cbd) + val colorAlphaBlue600 = Color(0x87015afe) + val colorAlphaBlue700 = Color(0xa30665fe) + val colorAlphaBlue800 = Color(0xd61077fe) + val colorAlphaBlue900 = Color(0xeb4491fd) + val colorAlphaCyan100 = Color(0xff001142) + val colorAlphaCyan1000 = Color(0xe000bfe0) + val colorAlphaCyan1100 = Color(0xc926e7fd) + val colorAlphaCyan1200 = Color(0xd98af1ff) + val colorAlphaCyan1300 = Color(0xebc9f7fd) + val colorAlphaCyan1400 = Color(0xf5e1fbfe) + val colorAlphaCyan200 = Color(0xff001447) + val colorAlphaCyan300 = Color(0xff001b4d) + val colorAlphaCyan400 = Color(0xff00265c) + val colorAlphaCyan500 = Color(0xff003366) + val colorAlphaCyan600 = Color(0xff003f75) + val colorAlphaCyan700 = Color(0xff00538a) + val colorAlphaCyan800 = Color(0xe0007ebd) + val colorAlphaCyan900 = Color(0xff0091bd) + val colorAlphaFuchsia100 = Color(0xff28003d) + val colorAlphaFuchsia1000 = Color(0xd4f790fe) + val colorAlphaFuchsia1100 = Color(0xdbfaa4fe) + val colorAlphaFuchsia1200 = Color(0xe8fac3fe) + val colorAlphaFuchsia1300 = Color(0xf2fde0ff) + val colorAlphaFuchsia1400 = Color(0xfafdecfe) + val colorAlphaFuchsia200 = Color(0xff2d0042) + val colorAlphaFuchsia300 = Color(0xff36004d) + val colorAlphaFuchsia400 = Color(0xff45005c) + val colorAlphaFuchsia500 = Color(0x61ca0aff) + val colorAlphaFuchsia600 = Color(0x70d21fff) + val colorAlphaFuchsia700 = Color(0x8ad82ffe) + val colorAlphaFuchsia800 = Color(0xb5eb44fd) + val colorAlphaFuchsia900 = Color(0xccf172fd) + val colorAlphaGray100 = Color(0x05d8dbdf) + val colorAlphaGray1000 = Color(0x9ce1eefe) + val colorAlphaGray1100 = Color(0xade7f0fe) + val colorAlphaGray1200 = Color(0xc9edf4fc) + val colorAlphaGray1300 = Color(0xe3f2f7fd) + val colorAlphaGray1400 = Color(0xf2f6f9fe) + val colorAlphaGray200 = Color(0x0ad9c3df) + val colorAlphaGray300 = Color(0x0fe9dbf0) + val colorAlphaGray400 = Color(0x1aede7f4) + val colorAlphaGray500 = Color(0x26f4f7fa) + val colorAlphaGray600 = Color(0x33eceff8) + val colorAlphaGray700 = Color(0x45e7f1fd) + val colorAlphaGray800 = Color(0x69e0edff) + val colorAlphaGray900 = Color(0x8ae1effe) + val colorAlphaGreen100 = Color(0xff001f0c) + val colorAlphaGreen1000 = Color(0xa61bfebd) + val colorAlphaGreen1100 = Color(0xbd26fdbc) + val colorAlphaGreen1200 = Color(0xd486fdce) + val colorAlphaGreen1300 = Color(0xe8c4fde2) + val colorAlphaGreen1400 = Color(0xf5e2fdf1) + val colorAlphaGreen200 = Color(0xff001f0e) + val colorAlphaGreen300 = Color(0xff002412) + val colorAlphaGreen400 = Color(0xff002e1b) + val colorAlphaGreen500 = Color(0xff003d29) + val colorAlphaGreen600 = Color(0xff004732) + val colorAlphaGreen700 = Color(0xff005c45) + val colorAlphaGreen800 = Color(0xff007a62) + val colorAlphaGreen900 = Color(0x9412fdbe) + val colorAlphaLime100 = Color(0xff001a00) + val colorAlphaLime1000 = Color(0xa860fc2c) + val colorAlphaLime1100 = Color(0xbd71fd35) + val colorAlphaLime1200 = Color(0xd68dff5c) + val colorAlphaLime1300 = Color(0xebc3ffad) + val colorAlphaLime1400 = Color(0xf7e1fdd8) + val colorAlphaLime200 = Color(0xff001f00) + val colorAlphaLime300 = Color(0xff002900) + val colorAlphaLime400 = Color(0xff002e00) + val colorAlphaLime500 = Color(0xff003d00) + val colorAlphaLime600 = Color(0xff004d00) + val colorAlphaLime700 = Color(0xff005c00) + val colorAlphaLime800 = Color(0x732dfd0d) + val colorAlphaLime900 = Color(0x9454fd26) + val colorAlphaOrange100 = Color(0xff380000) + val colorAlphaOrange1000 = Color(0xebfe8310) + val colorAlphaOrange1100 = Color(0xf7fd953f) + val colorAlphaOrange1200 = Color(0xfcfdb781) + val colorAlphaOrange1300 = Color(0xffffd4b8) + val colorAlphaOrange1400 = Color(0xffffeadb) + val colorAlphaOrange200 = Color(0xff3d0000) + val colorAlphaOrange300 = Color(0xff470000) + val colorAlphaOrange400 = Color(0xff570000) + val colorAlphaOrange500 = Color(0xff700000) + val colorAlphaOrange600 = Color(0xff850400) + val colorAlphaOrange700 = Color(0xbdc72800) + val colorAlphaOrange800 = Color(0xb5ff5900) + val colorAlphaOrange900 = Color(0xd9fe740b) + val colorAlphaPink100 = Color(0xff38000f) + val colorAlphaPink1000 = Color(0xfaff6691) + val colorAlphaPink1100 = Color(0xfffe86a4) + val colorAlphaPink1200 = Color(0xffffadc0) + val colorAlphaPink1300 = Color(0xffffd1db) + val colorAlphaPink1400 = Color(0xffffebef) + val colorAlphaPink200 = Color(0xff3d0012) + val colorAlphaPink300 = Color(0xff470019) + val colorAlphaPink400 = Color(0xff570024) + val colorAlphaPink500 = Color(0xff6b0036) + val colorAlphaPink600 = Color(0x75fb0473) + val colorAlphaPink700 = Color(0x94fd1277) + val colorAlphaPink800 = Color(0xccfe1b79) + val colorAlphaPink900 = Color(0xf5fe4382) + val colorAlphaPurple100 = Color(0xff1a0057) + val colorAlphaPurple1000 = Color(0xfca28bfe) + val colorAlphaPurple1100 = Color(0xffab9afe) + val colorAlphaPurple1200 = Color(0xffc7bdff) + val colorAlphaPurple1300 = Color(0xffdfdbff) + val colorAlphaPurple1400 = Color(0xffeeebff) + val colorAlphaPurple200 = Color(0xff1d005c) + val colorAlphaPurple300 = Color(0xff22006b) + val colorAlphaPurple400 = Color(0xff2d0080) + val colorAlphaPurple500 = Color(0xff3d009e) + val colorAlphaPurple600 = Color(0xab690dfd) + val colorAlphaPurple700 = Color(0xc2712bfd) + val colorAlphaPurple800 = Color(0xeb7f4dff) + val colorAlphaPurple900 = Color(0xfa9271fe) + val colorAlphaRed100 = Color(0xff380000) + val colorAlphaRed1000 = Color(0xffff645c) + val colorAlphaRed1100 = Color(0xffff857a) + val colorAlphaRed1200 = Color(0xffffaea3) + val colorAlphaRed1300 = Color(0xffffd3cc) + val colorAlphaRed1400 = Color(0xffffe8e5) + val colorAlphaRed200 = Color(0xff3d0000) + val colorAlphaRed300 = Color(0xff470000) + val colorAlphaRed400 = Color(0xff5c0000) + val colorAlphaRed500 = Color(0xff700000) + val colorAlphaRed600 = Color(0xff850009) + val colorAlphaRed700 = Color(0x99fe0b24) + val colorAlphaRed800 = Color(0xcffe2530) + val colorAlphaRed900 = Color(0xfffd3d3a) + val colorAlphaYellow100 = Color(0xff380000) + val colorAlphaYellow1000 = Color(0xffcc8b00) + val colorAlphaYellow1100 = Color(0xffdba100) + val colorAlphaYellow1200 = Color(0xf0fdc50d) + val colorAlphaYellow1300 = Color(0xfffeda58) + val colorAlphaYellow1400 = Color(0xffffedb3) + val colorAlphaYellow200 = Color(0xff380300) + val colorAlphaYellow300 = Color(0xff420900) + val colorAlphaYellow400 = Color(0xff4d1400) + val colorAlphaYellow500 = Color(0xff5c2300) + val colorAlphaYellow600 = Color(0xde753300) + val colorAlphaYellow700 = Color(0xeb854200) + val colorAlphaYellow800 = Color(0xff9e5c00) + val colorAlphaYellow900 = Color(0xffbd7b00) + val colorBlue100 = Color(0xff00055a) + val colorBlue1000 = Color(0xff5e99f0) + val colorBlue1100 = Color(0xff7aacf4) + val colorBlue1200 = Color(0xffa1c4f8) + val colorBlue1300 = Color(0xffcbdffc) + val colorBlue1400 = Color(0xffe4eefe) + val colorBlue200 = Color(0xff00095d) + val colorBlue300 = Color(0xff001264) + val colorBlue400 = Color(0xff001e6f) + val colorBlue500 = Color(0xff062d80) + val colorBlue600 = Color(0xff083891) + val colorBlue700 = Color(0xff0b49ab) + val colorBlue800 = Color(0xff0e67d9) + val colorBlue900 = Color(0xff4187eb) + val colorCyan100 = Color(0xff001144) + val colorCyan1000 = Color(0xff02a7c6) + val colorCyan1100 = Color(0xff21bacd) + val colorCyan1200 = Color(0xff78d0dc) + val colorCyan1300 = Color(0xffb8e5eb) + val colorCyan1400 = Color(0xffdbf2f5) + val colorCyan200 = Color(0xff001448) + val colorCyan300 = Color(0xff001b4e) + val colorCyan400 = Color(0xff002559) + val colorCyan500 = Color(0xff003468) + val colorCyan600 = Color(0xff003f75) + val colorCyan700 = Color(0xff005188) + val colorCyan800 = Color(0xff0271aa) + val colorCyan900 = Color(0xff0093be) + val colorFuchsia100 = Color(0xff28003d) + val colorFuchsia1000 = Color(0xffcf78d7) + val colorFuchsia1100 = Color(0xffd991de) + val colorFuchsia1200 = Color(0xffe5b1e9) + val colorFuchsia1300 = Color(0xfff1d4f3) + val colorFuchsia1400 = Color(0xfff8e9f9) + val colorFuchsia200 = Color(0xff2e0044) + val colorFuchsia300 = Color(0xff37004e) + val colorFuchsia400 = Color(0xff46005e) + val colorFuchsia500 = Color(0xff560f6f) + val colorFuchsia600 = Color(0xff65177d) + val colorFuchsia700 = Color(0xff7d2394) + val colorFuchsia800 = Color(0xffaa36ba) + val colorFuchsia900 = Color(0xffc560cf) + val colorGray100 = Color(0xff14171b) + val colorGray1000 = Color(0xff9199a4) + val colorGray1100 = Color(0xffa3aab4) + val colorGray1200 = Color(0xffbdc3cc) + val colorGray1300 = Color(0xffd9dee4) + val colorGray1400 = Color(0xffebeef2) + val colorGray200 = Color(0xff181a1f) + val colorGray300 = Color(0xff1d1f24) + val colorGray400 = Color(0xff26282d) + val colorGray500 = Color(0xff323539) + val colorGray600 = Color(0xff3c3f44) + val colorGray700 = Color(0xff4a4f55) + val colorGray800 = Color(0xff656c76) + val colorGray900 = Color(0xff808994) + val colorGreen100 = Color(0xff001c0b) + val colorGreen1000 = Color(0xff17ac84) + val colorGreen1100 = Color(0xff1fc090) + val colorGreen1200 = Color(0xff72d5ae) + val colorGreen1300 = Color(0xffb5e8d1) + val colorGreen1400 = Color(0xffd9f4e7) + val colorGreen200 = Color(0xff001f0e) + val colorGreen300 = Color(0xff002513) + val colorGreen400 = Color(0xff002e1b) + val colorGreen500 = Color(0xff003d29) + val colorGreen600 = Color(0xff004832) + val colorGreen700 = Color(0xff005a43) + val colorGreen800 = Color(0xff007a62) + val colorGreen900 = Color(0xff129a78) + val colorLime100 = Color(0xff001b00) + val colorLime1000 = Color(0xff47ad26) + val colorLime1100 = Color(0xff56c02c) + val colorLime1200 = Color(0xff77d94f) + val colorLime1300 = Color(0xffb6eca3) + val colorLime1400 = Color(0xffdaf6d0) + val colorLime200 = Color(0xff002000) + val colorLime300 = Color(0xff002600) + val colorLime400 = Color(0xff003000) + val colorLime500 = Color(0xff003e00) + val colorLime600 = Color(0xff004a00) + val colorLime700 = Color(0xff005c00) + val colorLime800 = Color(0xff1d7c13) + val colorLime900 = Color(0xff389b20) + val colorOrange100 = Color(0xff380000) + val colorOrange1000 = Color(0xffeb7a12) + val colorOrange1100 = Color(0xfff6913d) + val colorOrange1200 = Color(0xfffbb37e) + val colorOrange1300 = Color(0xffffd5b9) + val colorOrange1400 = Color(0xffffeadb) + val colorOrange200 = Color(0xff3c0000) + val colorOrange300 = Color(0xff470000) + val colorOrange400 = Color(0xff580000) + val colorOrange500 = Color(0xff710000) + val colorOrange600 = Color(0xff830500) + val colorOrange700 = Color(0xff972206) + val colorOrange800 = Color(0xffb94607) + val colorOrange900 = Color(0xffda670d) + val colorPink100 = Color(0xff37000f) + val colorPink1000 = Color(0xfffa658f) + val colorPink1100 = Color(0xfffe84a2) + val colorPink1200 = Color(0xffffabbe) + val colorPink1300 = Color(0xffffd2dc) + val colorPink1400 = Color(0xffffe8ed) + val colorPink200 = Color(0xff3c0012) + val colorPink300 = Color(0xff450018) + val colorPink400 = Color(0xff550024) + val colorPink500 = Color(0xff6d0036) + val colorPink600 = Color(0xff7c0c41) + val colorPink700 = Color(0xff99114f) + val colorPink800 = Color(0xffce1865) + val colorPink900 = Color(0xfff4427d) + val colorPurple100 = Color(0xff1a0055) + val colorPurple1000 = Color(0xff9e87fc) + val colorPurple1100 = Color(0xffad9cfe) + val colorPurple1200 = Color(0xffc4baff) + val colorPurple1300 = Color(0xffdedaff) + val colorPurple1400 = Color(0xffeeebff) + val colorPurple200 = Color(0xff1c005a) + val colorPurple300 = Color(0xff22006a) + val colorPurple400 = Color(0xff2c0080) + val colorPurple500 = Color(0xff3d009e) + val colorPurple600 = Color(0xff4a0db1) + val colorPurple700 = Color(0xff5a27c6) + val colorPurple800 = Color(0xff7849ec) + val colorPurple900 = Color(0xff9171f9) + val colorRed100 = Color(0xff370000) + val colorRed1000 = Color(0xffff665d) + val colorRed1100 = Color(0xffff877c) + val colorRed1200 = Color(0xffffaea4) + val colorRed1300 = Color(0xffffd4cd) + val colorRed1400 = Color(0xffffe9e6) + val colorRed200 = Color(0xff3e0000) + val colorRed300 = Color(0xff470000) + val colorRed400 = Color(0xff590000) + val colorRed500 = Color(0xff710000) + val colorRed600 = Color(0xff830009) + val colorRed700 = Color(0xff9f0d1e) + val colorRed800 = Color(0xffd1212a) + val colorRed900 = Color(0xfffd3e3c) + val colorThemeBg = Color(0xff101317) + val colorTransparent = Color(0x00000000) + val colorYellow100 = Color(0xff360000) + val colorYellow1000 = Color(0xffcc8c00) + val colorYellow1100 = Color(0xffdb9f00) + val colorYellow1200 = Color(0xffefbb0b) + val colorYellow1300 = Color(0xfffedb58) + val colorYellow1400 = Color(0xffffedb1) + val colorYellow200 = Color(0xff3a0300) + val colorYellow300 = Color(0xff410900) + val colorYellow400 = Color(0xff4c1400) + val colorYellow500 = Color(0xff5c2400) + val colorYellow600 = Color(0xff682e03) + val colorYellow700 = Color(0xff7c3e02) + val colorYellow800 = Color(0xff9d5b00) + val colorYellow900 = Color(0xffbc7a00) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt new file mode 100644 index 0000000000..31406f6ffc --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt @@ -0,0 +1,335 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated.internal + +import androidx.compose.ui.graphics.Color +import io.element.android.compound.annotations.CoreColorToken + +@CoreColorToken +object DarkHcColorTokens { + val colorAlphaBlue100 = Color(0xff00095c) + val colorAlphaBlue1000 = Color(0xf79ec5ff) + val colorAlphaBlue1100 = Color(0xfab8d4ff) + val colorAlphaBlue1200 = Color(0xfcc8defe) + val colorAlphaBlue1300 = Color(0xffe6effe) + val colorAlphaBlue1400 = Color(0xfff1f6fe) + val colorAlphaBlue200 = Color(0xff001366) + val colorAlphaBlue300 = Color(0xff001e70) + val colorAlphaBlue400 = Color(0xd1002b8f) + val colorAlphaBlue500 = Color(0x87015afe) + val colorAlphaBlue600 = Color(0xa30665fe) + val colorAlphaBlue700 = Color(0xcf0d71fd) + val colorAlphaBlue800 = Color(0xe83488fe) + val colorAlphaBlue900 = Color(0xf78bb9fd) + val colorAlphaCyan100 = Color(0xff001447) + val colorAlphaCyan1000 = Color(0xd67beffe) + val colorAlphaCyan1100 = Color(0xe0a4f4fe) + val colorAlphaCyan1200 = Color(0xe8bef5fe) + val colorAlphaCyan1300 = Color(0xf5e1fbfe) + val colorAlphaCyan1400 = Color(0xfaf1fdfe) + val colorAlphaCyan200 = Color(0xff001b4d) + val colorAlphaCyan300 = Color(0xff00265c) + val colorAlphaCyan400 = Color(0xff002d61) + val colorAlphaCyan500 = Color(0xff003f75) + val colorAlphaCyan600 = Color(0xff00538a) + val colorAlphaCyan700 = Color(0xff006da3) + val colorAlphaCyan800 = Color(0xff008ebd) + val colorAlphaCyan900 = Color(0xcf52edfe) + val colorAlphaFuchsia100 = Color(0xff2d0042) + val colorAlphaFuchsia1000 = Color(0xe6fabefe) + val colorAlphaFuchsia1100 = Color(0xedfacefd) + val colorAlphaFuchsia1200 = Color(0xf2fcd7fe) + val colorAlphaFuchsia1300 = Color(0xfafdecfe) + val colorAlphaFuchsia1400 = Color(0xfcfdf2fd) + val colorAlphaFuchsia200 = Color(0xff36004d) + val colorAlphaFuchsia300 = Color(0xff45005c) + val colorAlphaFuchsia400 = Color(0xd95a0075) + val colorAlphaFuchsia500 = Color(0x70d21fff) + val colorAlphaFuchsia600 = Color(0x8ad82ffe) + val colorAlphaFuchsia700 = Color(0xade640fc) + val colorAlphaFuchsia800 = Color(0xc7f467fe) + val colorAlphaFuchsia900 = Color(0xe0f9b3ff) + val colorAlphaGray100 = Color(0x0ad9c3df) + val colorAlphaGray1000 = Color(0xc2f0f7ff) + val colorAlphaGray1100 = Color(0xd1f0f7ff) + val colorAlphaGray1200 = Color(0xe0f1f6fd) + val colorAlphaGray1300 = Color(0xf2f6f9fe) + val colorAlphaGray1400 = Color(0xf7fbfdfe) + val colorAlphaGray200 = Color(0x0fe9dbf0) + val colorAlphaGray300 = Color(0x1aede7f4) + val colorAlphaGray400 = Color(0x21e1e4ef) + val colorAlphaGray500 = Color(0x33eceff8) + val colorAlphaGray600 = Color(0x45e7f1fd) + val colorAlphaGray700 = Color(0x63dfebfb) + val colorAlphaGray800 = Color(0x82dceafe) + val colorAlphaGray900 = Color(0xb8ecf4fe) + val colorAlphaGreen100 = Color(0xff001f0e) + val colorAlphaGreen1000 = Color(0xcf75ffc8) + val colorAlphaGreen1100 = Color(0xdba4fed7) + val colorAlphaGreen1200 = Color(0xe6bffde1) + val colorAlphaGreen1300 = Color(0xf5e2fdf1) + val colorAlphaGreen1400 = Color(0xfaedfdf5) + val colorAlphaGreen200 = Color(0xff002412) + val colorAlphaGreen300 = Color(0xff002e1b) + val colorAlphaGreen400 = Color(0xff003824) + val colorAlphaGreen500 = Color(0xff004732) + val colorAlphaGreen600 = Color(0xff005c45) + val colorAlphaGreen700 = Color(0xff00755e) + val colorAlphaGreen800 = Color(0x8a12fdc2) + val colorAlphaGreen900 = Color(0xc740fcba) + val colorAlphaLime100 = Color(0xff001f00) + val colorAlphaLime1000 = Color(0xd47bfe3e) + val colorAlphaLime1100 = Color(0xe0a4fd81) + val colorAlphaLime1200 = Color(0xe8c1fea9) + val colorAlphaLime1300 = Color(0xf7e1fdd8) + val colorAlphaLime1400 = Color(0xfaedfee7) + val colorAlphaLime200 = Color(0xff002900) + val colorAlphaLime300 = Color(0xff002e00) + val colorAlphaLime400 = Color(0xff003800) + val colorAlphaLime500 = Color(0xff004d00) + val colorAlphaLime600 = Color(0xff005c00) + val colorAlphaLime700 = Color(0x6b23ff0a) + val colorAlphaLime800 = Color(0x8c4dfe25) + val colorAlphaLime900 = Color(0xc774fe34) + val colorAlphaOrange100 = Color(0xff3d0000) + val colorAlphaOrange1000 = Color(0xfaffb175) + val colorAlphaOrange1100 = Color(0xfffdc196) + val colorAlphaOrange1200 = Color(0xfffed1b3) + val colorAlphaOrange1300 = Color(0xffffeadb) + val colorAlphaOrange1400 = Color(0xfffff2eb) + val colorAlphaOrange200 = Color(0xff470000) + val colorAlphaOrange300 = Color(0xff570000) + val colorAlphaOrange400 = Color(0xff660000) + val colorAlphaOrange500 = Color(0xff850400) + val colorAlphaOrange600 = Color(0xbdc72800) + val colorAlphaOrange700 = Color(0xb3fa5300) + val colorAlphaOrange800 = Color(0xcffe7206) + val colorAlphaOrange900 = Color(0xfafda058) + val colorAlphaPink100 = Color(0xff3d0012) + val colorAlphaPink1000 = Color(0xffffa3b9) + val colorAlphaPink1100 = Color(0xffffbdcb) + val colorAlphaPink1200 = Color(0xffffccd7) + val colorAlphaPink1300 = Color(0xffffebef) + val colorAlphaPink1400 = Color(0xfffff0f3) + val colorAlphaPink200 = Color(0xff470019) + val colorAlphaPink300 = Color(0xff570024) + val colorAlphaPink400 = Color(0xff61002d) + val colorAlphaPink500 = Color(0x75fb0473) + val colorAlphaPink600 = Color(0x94fd1277) + val colorAlphaPink700 = Color(0xc2fe1b79) + val colorAlphaPink800 = Color(0xf2fd2b78) + val colorAlphaPink900 = Color(0xffff94ad) + val colorAlphaPurple100 = Color(0xff1d005c) + val colorAlphaPurple1000 = Color(0xffc2b8ff) + val colorAlphaPurple1100 = Color(0xffcec7ff) + val colorAlphaPurple1200 = Color(0xffdbd6ff) + val colorAlphaPurple1300 = Color(0xffeeebff) + val colorAlphaPurple1400 = Color(0xfff6f5ff) + val colorAlphaPurple200 = Color(0xff22006b) + val colorAlphaPurple300 = Color(0xff2d0080) + val colorAlphaPurple400 = Color(0xff34008f) + val colorAlphaPurple500 = Color(0xab690dfd) + val colorAlphaPurple600 = Color(0xc2712bfd) + val colorAlphaPurple700 = Color(0xe67f49fd) + val colorAlphaPurple800 = Color(0xf7906bff) + val colorAlphaPurple900 = Color(0xffb7a8ff) + val colorAlphaRed100 = Color(0xff3d0000) + val colorAlphaRed1000 = Color(0xffffa89e) + val colorAlphaRed1100 = Color(0xffffbfb8) + val colorAlphaRed1200 = Color(0xffffcec7) + val colorAlphaRed1300 = Color(0xffffe8e5) + val colorAlphaRed1400 = Color(0xfffff3f0) + val colorAlphaRed200 = Color(0xff470000) + val colorAlphaRed300 = Color(0xff5c0000) + val colorAlphaRed400 = Color(0xff660000) + val colorAlphaRed500 = Color(0xff850009) + val colorAlphaRed600 = Color(0x99fe0b24) + val colorAlphaRed700 = Color(0xc4ff242f) + val colorAlphaRed800 = Color(0xf5ff2e31) + val colorAlphaRed900 = Color(0xffff988f) + val colorAlphaYellow100 = Color(0xff380300) + val colorAlphaYellow1000 = Color(0xebfec406) + val colorAlphaYellow1100 = Color(0xf7fecf16) + val colorAlphaYellow1200 = Color(0xfffed634) + val colorAlphaYellow1300 = Color(0xffffedb3) + val colorAlphaYellow1400 = Color(0xfffff4d1) + val colorAlphaYellow200 = Color(0xff420900) + val colorAlphaYellow300 = Color(0xff4d1400) + val colorAlphaYellow400 = Color(0xff571e00) + val colorAlphaYellow500 = Color(0xde753300) + val colorAlphaYellow600 = Color(0xeb854200) + val colorAlphaYellow700 = Color(0xff995700) + val colorAlphaYellow800 = Color(0xffb37100) + val colorAlphaYellow900 = Color(0xffe6ac00) + val colorBlue100 = Color(0xff00095d) + val colorBlue1000 = Color(0xff9ac0f8) + val colorBlue1100 = Color(0xffb2cffa) + val colorBlue1200 = Color(0xffc5dbfc) + val colorBlue1300 = Color(0xffe4eefe) + val colorBlue1400 = Color(0xffeff5fe) + val colorBlue200 = Color(0xff001264) + val colorBlue300 = Color(0xff001e6f) + val colorBlue400 = Color(0xff032677) + val colorBlue500 = Color(0xff083891) + val colorBlue600 = Color(0xff0b49ab) + val colorBlue700 = Color(0xff0e61d1) + val colorBlue800 = Color(0xff337fe9) + val colorBlue900 = Color(0xff89b5f6) + val colorCyan100 = Color(0xff001448) + val colorCyan1000 = Color(0xff6bccd9) + val colorCyan1100 = Color(0xff93d9e2) + val colorCyan1200 = Color(0xffafe2e9) + val colorCyan1300 = Color(0xffdbf2f5) + val colorCyan1400 = Color(0xffeaf7f9) + val colorCyan200 = Color(0xff001b4e) + val colorCyan300 = Color(0xff002559) + val colorCyan400 = Color(0xff002d61) + val colorCyan500 = Color(0xff003f75) + val colorCyan600 = Color(0xff005188) + val colorCyan700 = Color(0xff006ca4) + val colorCyan800 = Color(0xff008aba) + val colorCyan900 = Color(0xff46c3d2) + val colorFuchsia100 = Color(0xff2e0044) + val colorFuchsia1000 = Color(0xffe3abe7) + val colorFuchsia1100 = Color(0xffeac0ed) + val colorFuchsia1200 = Color(0xfff0cff2) + val colorFuchsia1300 = Color(0xfff8e9f9) + val colorFuchsia1400 = Color(0xfffbf1fb) + val colorFuchsia200 = Color(0xff37004e) + val colorFuchsia300 = Color(0xff46005e) + val colorFuchsia400 = Color(0xff4f0368) + val colorFuchsia500 = Color(0xff65177d) + val colorFuchsia600 = Color(0xff7d2394) + val colorFuchsia700 = Color(0xffa233b3) + val colorFuchsia800 = Color(0xffc153cb) + val colorFuchsia900 = Color(0xffdd9de3) + val colorGray100 = Color(0xff181a1f) + val colorGray1000 = Color(0xffb8bfc7) + val colorGray1100 = Color(0xffc8ced5) + val colorGray1200 = Color(0xffd5dae1) + val colorGray1300 = Color(0xffebeef2) + val colorGray1400 = Color(0xfff2f5f7) + val colorGray200 = Color(0xff1d1f24) + val colorGray300 = Color(0xff26282d) + val colorGray400 = Color(0xff2b2e33) + val colorGray500 = Color(0xff3c3f44) + val colorGray600 = Color(0xff4a4f55) + val colorGray700 = Color(0xff606770) + val colorGray800 = Color(0xff79818d) + val colorGray900 = Color(0xffacb4bd) + val colorGreen100 = Color(0xff001f0e) + val colorGreen1000 = Color(0xff61d2a6) + val colorGreen1100 = Color(0xff8fddbc) + val colorGreen1200 = Color(0xfface6cc) + val colorGreen1300 = Color(0xffd9f4e7) + val colorGreen1400 = Color(0xffe9f8f1) + val colorGreen200 = Color(0xff002513) + val colorGreen300 = Color(0xff002e1b) + val colorGreen400 = Color(0xff003622) + val colorGreen500 = Color(0xff004832) + val colorGreen600 = Color(0xff005a43) + val colorGreen700 = Color(0xff00745c) + val colorGreen800 = Color(0xff109173) + val colorGreen900 = Color(0xff37c998) + val colorLime100 = Color(0xff002000) + val colorLime1000 = Color(0xff6ad639) + val colorLime1100 = Color(0xff92e175) + val colorLime1200 = Color(0xffafe99a) + val colorLime1300 = Color(0xffdaf6d0) + val colorLime1400 = Color(0xffe9f9e3) + val colorLime200 = Color(0xff002600) + val colorLime300 = Color(0xff003000) + val colorLime400 = Color(0xff003700) + val colorLime500 = Color(0xff004a00) + val colorLime600 = Color(0xff005c00) + val colorLime700 = Color(0xff187611) + val colorLime800 = Color(0xff31941d) + val colorLime900 = Color(0xff5eca2f) + val colorOrange100 = Color(0xff3c0000) + val colorOrange1000 = Color(0xfffaad73) + val colorOrange1100 = Color(0xfffdc197) + val colorOrange1200 = Color(0xfffed0b1) + val colorOrange1300 = Color(0xffffeadb) + val colorOrange1400 = Color(0xfffff2ea) + val colorOrange200 = Color(0xff470000) + val colorOrange300 = Color(0xff580000) + val colorOrange400 = Color(0xff650000) + val colorOrange500 = Color(0xff830500) + val colorOrange600 = Color(0xff972206) + val colorOrange700 = Color(0xffb44007) + val colorOrange800 = Color(0xffd15f0b) + val colorOrange900 = Color(0xfff89d58) + val colorPink100 = Color(0xff3c0012) + val colorPink1000 = Color(0xffffa4b9) + val colorPink1100 = Color(0xffffbbca) + val colorPink1200 = Color(0xffffccd7) + val colorPink1300 = Color(0xffffe8ed) + val colorPink1400 = Color(0xfffff1f4) + val colorPink200 = Color(0xff450018) + val colorPink300 = Color(0xff550024) + val colorPink400 = Color(0xff61002d) + val colorPink500 = Color(0xff7c0c41) + val colorPink600 = Color(0xff99114f) + val colorPink700 = Color(0xffc51761) + val colorPink800 = Color(0xfff12c75) + val colorPink900 = Color(0xffff92ac) + val colorPurple100 = Color(0xff1c005a) + val colorPurple1000 = Color(0xffc0b5ff) + val colorPurple1100 = Color(0xffcec7ff) + val colorPurple1200 = Color(0xffdad5ff) + val colorPurple1300 = Color(0xffeeebff) + val colorPurple1400 = Color(0xfff5f3ff) + val colorPurple200 = Color(0xff22006a) + val colorPurple300 = Color(0xff2c0080) + val colorPurple400 = Color(0xff350090) + val colorPurple500 = Color(0xff4a0db1) + val colorPurple600 = Color(0xff5a27c6) + val colorPurple700 = Color(0xff7343e6) + val colorPurple800 = Color(0xff8b66f8) + val colorPurple900 = Color(0xffb6a7ff) + val colorRed100 = Color(0xff3e0000) + val colorRed1000 = Color(0xffffa79d) + val colorRed1100 = Color(0xffffbdb5) + val colorRed1200 = Color(0xffffcfc8) + val colorRed1300 = Color(0xffffe9e6) + val colorRed1400 = Color(0xfffff2ef) + val colorRed200 = Color(0xff470000) + val colorRed300 = Color(0xff590000) + val colorRed400 = Color(0xff640000) + val colorRed500 = Color(0xff830009) + val colorRed600 = Color(0xff9f0d1e) + val colorRed700 = Color(0xffc81e28) + val colorRed800 = Color(0xfff52f33) + val colorRed900 = Color(0xffff968c) + val colorThemeBg = Color(0xff101317) + val colorTransparent = Color(0x00000000) + val colorYellow100 = Color(0xff3a0300) + val colorYellow1000 = Color(0xffebb607) + val colorYellow1100 = Color(0xfff7c816) + val colorYellow1200 = Color(0xfffed632) + val colorYellow1300 = Color(0xffffedb1) + val colorYellow1400 = Color(0xfffff4d0) + val colorYellow200 = Color(0xff410900) + val colorYellow300 = Color(0xff4c1400) + val colorYellow400 = Color(0xff541d00) + val colorYellow500 = Color(0xff682e03) + val colorYellow600 = Color(0xff7c3e02) + val colorYellow700 = Color(0xff985600) + val colorYellow800 = Color(0xffb47200) + val colorYellow900 = Color(0xffe3aa00) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt new file mode 100644 index 0000000000..119db9dade --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt @@ -0,0 +1,335 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated.internal + +import androidx.compose.ui.graphics.Color +import io.element.android.compound.annotations.CoreColorToken + +@CoreColorToken +object LightColorTokens { + val colorAlphaBlue100 = Color(0x08389cff) + val colorAlphaBlue1000 = Color(0xfc0256c5) + val colorAlphaBlue1100 = Color(0xfa0148b2) + val colorAlphaBlue1200 = Color(0xfc013693) + val colorAlphaBlue1300 = Color(0xff012579) + val colorAlphaBlue1400 = Color(0xff000e66) + val colorAlphaBlue200 = Color(0x0d2474ff) + val colorAlphaBlue300 = Color(0x170a70ff) + val colorAlphaBlue400 = Color(0x290b6af9) + val colorAlphaBlue500 = Color(0x47096cf6) + val colorAlphaBlue600 = Color(0x5e0663ef) + val colorAlphaBlue700 = Color(0x820264ed) + val colorAlphaBlue800 = Color(0xbf0062eb) + val colorAlphaBlue900 = Color(0xfc0165df) + val colorAlphaCyan100 = Color(0x0816bbbb) + val colorAlphaCyan1000 = Color(0xff00649e) + val colorAlphaCyan1100 = Color(0xff00568f) + val colorAlphaCyan1200 = Color(0xff003f75) + val colorAlphaCyan1300 = Color(0xff002c61) + val colorAlphaCyan1400 = Color(0xff001a52) + val colorAlphaCyan200 = Color(0x0f16abbb) + val colorAlphaCyan300 = Color(0x1c00a8c2) + val colorAlphaCyan400 = Color(0x3800aabd) + val colorAlphaCyan500 = Color(0x6605abbd) + val colorAlphaCyan600 = Color(0x8a01aac1) + val colorAlphaCyan700 = Color(0xeb01b7cb) + val colorAlphaCyan800 = Color(0xff0095c2) + val colorAlphaCyan900 = Color(0xff0074ad) + val colorAlphaFuchsia100 = Color(0x05cc05cc) + val colorAlphaFuchsia1000 = Color(0xd6820198) + val colorAlphaFuchsia1100 = Color(0xe073038c) + val colorAlphaFuchsia1200 = Color(0xed5d0279) + val colorAlphaFuchsia1300 = Color(0xff4d0066) + val colorAlphaFuchsia1400 = Color(0xff34004d) + val colorAlphaFuchsia200 = Color(0x0ab505cc) + val colorAlphaFuchsia300 = Color(0x12b60cc6) + val colorAlphaFuchsia400 = Color(0x21bd09c3) + val colorAlphaFuchsia500 = Color(0x3bb407c0) + val colorAlphaFuchsia600 = Color(0x4fb207bb) + val colorAlphaFuchsia700 = Color(0x6eaa04b9) + val colorAlphaFuchsia800 = Color(0xa3ab03ba) + val colorAlphaFuchsia900 = Color(0xcc9900ad) + val colorAlphaGray100 = Color(0x0536699b) + val colorAlphaGray1000 = Color(0xa8030c1b) + val colorAlphaGray1100 = Color(0xb5030b16) + val colorAlphaGray1200 = Color(0xc402070d) + val colorAlphaGray1300 = Color(0xd603050c) + val colorAlphaGray1400 = Color(0xe6020408) + val colorAlphaGray200 = Color(0x0a366881) + val colorAlphaGray300 = Color(0x0f052657) + val colorAlphaGray400 = Color(0x1f052e61) + val colorAlphaGray500 = Color(0x33052448) + val colorAlphaGray600 = Color(0x42011d3c) + val colorAlphaGray700 = Color(0x59011532) + val colorAlphaGray800 = Color(0x8003152b) + val colorAlphaGray900 = Color(0x9c031021) + val colorAlphaGreen100 = Color(0x0816bb79) + val colorAlphaGreen1000 = Color(0xff006b52) + val colorAlphaGreen1100 = Color(0xff005c45) + val colorAlphaGreen1200 = Color(0xff004732) + val colorAlphaGreen1300 = Color(0xff00331f) + val colorAlphaGreen1400 = Color(0xff002411) + val colorAlphaGreen200 = Color(0x0f16bb69) + val colorAlphaGreen300 = Color(0x1c00b85c) + val colorAlphaGreen400 = Color(0x3b07b661) + val colorAlphaGreen500 = Color(0x6904b96a) + val colorAlphaGreen600 = Color(0x8f01b76e) + val colorAlphaGreen700 = Color(0xf501c18a) + val colorAlphaGreen800 = Color(0xff009975) + val colorAlphaGreen900 = Color(0xff007a62) + val colorAlphaLime100 = Color(0x0a4fcd1d) + val colorAlphaLime1000 = Color(0xff007000) + val colorAlphaLime1100 = Color(0xff006100) + val colorAlphaLime1200 = Color(0xff004d00) + val colorAlphaLime1300 = Color(0xff003800) + val colorAlphaLime1400 = Color(0xff002400) + val colorAlphaLime200 = Color(0x1238d40c) + val colorAlphaLime300 = Color(0x262ecf02) + val colorAlphaLime400 = Color(0x473ace09) + val colorAlphaLime500 = Color(0x8237ca02) + val colorAlphaLime600 = Color(0xb540ce03) + val colorAlphaLime700 = Color(0xdb39bd00) + val colorAlphaLime800 = Color(0xe8209301) + val colorAlphaLime900 = Color(0xf5107902) + val colorAlphaOrange100 = Color(0x0aff8138) + val colorAlphaOrange1000 = Color(0xffad3400) + val colorAlphaOrange1100 = Color(0xff992100) + val colorAlphaOrange1200 = Color(0xff850000) + val colorAlphaOrange1300 = Color(0xff610000) + val colorAlphaOrange1400 = Color(0xff470000) + val colorAlphaOrange200 = Color(0x12ff7d1a) + val colorAlphaOrange300 = Color(0x1cff6c0a) + val colorAlphaOrange400 = Color(0x38ff6d05) + val colorAlphaOrange500 = Color(0x5eff6a00) + val colorAlphaOrange600 = Color(0x85fc6f03) + val colorAlphaOrange700 = Color(0xbff56e00) + val colorAlphaOrange800 = Color(0xffdb6600) + val colorAlphaOrange900 = Color(0xffbd4500) + val colorAlphaPink100 = Color(0x05ff0537) + val colorAlphaPink1000 = Color(0xf7b60256) + val colorAlphaPink1100 = Color(0xf79e004c) + val colorAlphaPink1200 = Color(0xfa79013d) + val colorAlphaPink1300 = Color(0xff61002c) + val colorAlphaPink1400 = Color(0xff420017) + val colorAlphaPink200 = Color(0x0aff0537) + val colorAlphaPink300 = Color(0x14ff1447) + val colorAlphaPink400 = Color(0x21ff0037) + val colorAlphaPink500 = Color(0x3dff0037) + val colorAlphaPink600 = Color(0x54ff053f) + val colorAlphaPink700 = Color(0x78ff0040) + val colorAlphaPink800 = Color(0xbff50052) + val colorAlphaPink900 = Color(0xf5cf025e) + val colorAlphaPurple100 = Color(0x053838ff) + val colorAlphaPurple1000 = Color(0xc94502d4) + val colorAlphaPurple1100 = Color(0xdb4303c4) + val colorAlphaPurple1200 = Color(0xfc4a02b6) + val colorAlphaPurple1300 = Color(0xff34008f) + val colorAlphaPurple1400 = Color(0xff200066) + val colorAlphaPurple200 = Color(0x0a5338ff) + val colorAlphaPurple300 = Color(0x12381aff) + val colorAlphaPurple400 = Color(0x1f2f0fff) + val colorAlphaPurple500 = Color(0x332605ff) + val colorAlphaPurple600 = Color(0x452b05ff) + val colorAlphaPurple700 = Color(0x613305ff) + val colorAlphaPurple800 = Color(0x8f3b01f9) + val colorAlphaPurple900 = Color(0xba4902ed) + val colorAlphaRed100 = Color(0x08ff5938) + val colorAlphaRed1000 = Color(0xf2bb0217) + val colorAlphaRed1100 = Color(0xfca2011c) + val colorAlphaRed1200 = Color(0xff850007) + val colorAlphaRed1300 = Color(0xff610000) + val colorAlphaRed1400 = Color(0xff470000) + val colorAlphaRed200 = Color(0x0aff391f) + val colorAlphaRed300 = Color(0x14ff3814) + val colorAlphaRed400 = Color(0x26ff2b0a) + val colorAlphaRed500 = Color(0x45ff2605) + val colorAlphaRed600 = Color(0x5cff2205) + val colorAlphaRed700 = Color(0x80ff1a05) + val colorAlphaRed800 = Color(0xc4ff0505) + val colorAlphaRed900 = Color(0xe8cf0213) + val colorAlphaYellow100 = Color(0x0fffcd05) + val colorAlphaYellow1000 = Color(0xff8f4c00) + val colorAlphaYellow1100 = Color(0xff804000) + val colorAlphaYellow1200 = Color(0xff6b2e00) + val colorAlphaYellow1300 = Color(0xff571b00) + val colorAlphaYellow1400 = Color(0xff420700) + val colorAlphaYellow200 = Color(0x21ffc70f) + val colorAlphaYellow300 = Color(0x40ffc905) + val colorAlphaYellow400 = Color(0x7dffc905) + val colorAlphaYellow500 = Color(0xfffacc00) + val colorAlphaYellow600 = Color(0xfff0bc00) + val colorAlphaYellow700 = Color(0xffe0a500) + val colorAlphaYellow800 = Color(0xffbd7b00) + val colorAlphaYellow900 = Color(0xff9e5a00) + val colorBlue100 = Color(0xfff9fcff) + val colorBlue1000 = Color(0xff0558c7) + val colorBlue1100 = Color(0xff064ab1) + val colorBlue1200 = Color(0xff043894) + val colorBlue1300 = Color(0xff012478) + val colorBlue1400 = Color(0xff000e65) + val colorBlue200 = Color(0xfff4f8ff) + val colorBlue300 = Color(0xffe9f2ff) + val colorBlue400 = Color(0xffd8e7fe) + val colorBlue500 = Color(0xffbad5fc) + val colorBlue600 = Color(0xffa3c6fa) + val colorBlue700 = Color(0xff7eaff6) + val colorBlue800 = Color(0xff4088ee) + val colorBlue900 = Color(0xff0467dd) + val colorCyan100 = Color(0xfff8fdfd) + val colorCyan1000 = Color(0xff00629c) + val colorCyan1100 = Color(0xff00548c) + val colorCyan1200 = Color(0xff004077) + val colorCyan1300 = Color(0xff002b61) + val colorCyan1400 = Color(0xff00194f) + val colorCyan200 = Color(0xfff1fafb) + val colorCyan300 = Color(0xffe3f5f8) + val colorCyan400 = Color(0xffc7ecf0) + val colorCyan500 = Color(0xff9bdde5) + val colorCyan600 = Color(0xff76d1dd) + val colorCyan700 = Color(0xff15becf) + val colorCyan800 = Color(0xff0094c0) + val colorCyan900 = Color(0xff0072ac) + val colorFuchsia100 = Color(0xfffefafe) + val colorFuchsia1000 = Color(0xff972aaa) + val colorFuchsia1100 = Color(0xff822198) + val colorFuchsia1200 = Color(0xff671481) + val colorFuchsia1300 = Color(0xff4e0068) + val colorFuchsia1400 = Color(0xff34004c) + val colorFuchsia200 = Color(0xfffcf5fd) + val colorFuchsia300 = Color(0xfffaeefb) + val colorFuchsia400 = Color(0xfff6dff7) + val colorFuchsia500 = Color(0xffedc6f0) + val colorFuchsia600 = Color(0xffe7b2ea) + val colorFuchsia700 = Color(0xffdb93e1) + val colorFuchsia800 = Color(0xffc85ed1) + val colorFuchsia900 = Color(0xffad33bd) + val colorGray100 = Color(0xfffbfcfd) + val colorGray1000 = Color(0xff595e67) + val colorGray1100 = Color(0xff4c5158) + val colorGray1200 = Color(0xff3c4045) + val colorGray1300 = Color(0xff2b2d32) + val colorGray1400 = Color(0xff1b1d22) + val colorGray200 = Color(0xfff7f9fa) + val colorGray300 = Color(0xfff0f2f5) + val colorGray400 = Color(0xffe1e6ec) + val colorGray500 = Color(0xffcdd3da) + val colorGray600 = Color(0xffbdc4cc) + val colorGray700 = Color(0xffa6adb7) + val colorGray800 = Color(0xff818a95) + val colorGray900 = Color(0xff656d77) + val colorGreen100 = Color(0xfff8fdfb) + val colorGreen1000 = Color(0xff006b52) + val colorGreen1100 = Color(0xff005c45) + val colorGreen1200 = Color(0xff004933) + val colorGreen1300 = Color(0xff003420) + val colorGreen1400 = Color(0xff002311) + val colorGreen200 = Color(0xfff1fbf6) + val colorGreen300 = Color(0xffe3f7ed) + val colorGreen400 = Color(0xffc6eedb) + val colorGreen500 = Color(0xff98e1c1) + val colorGreen600 = Color(0xff71d7ae) + val colorGreen700 = Color(0xff0bc491) + val colorGreen800 = Color(0xff009b78) + val colorGreen900 = Color(0xff007a61) + val colorLime100 = Color(0xfff8fdf6) + val colorLime1000 = Color(0xff006e00) + val colorLime1100 = Color(0xff005f00) + val colorLime1200 = Color(0xff004b00) + val colorLime1300 = Color(0xff003600) + val colorLime1400 = Color(0xff002400) + val colorLime200 = Color(0xfff1fcee) + val colorLime300 = Color(0xffe0f8d9) + val colorLime400 = Color(0xffc8f1ba) + val colorLime500 = Color(0xff99e57e) + val colorLime600 = Color(0xff76db4c) + val colorLime700 = Color(0xff54c424) + val colorLime800 = Color(0xff359d18) + val colorLime900 = Color(0xff197d0c) + val colorOrange100 = Color(0xfffffaf7) + val colorOrange1000 = Color(0xffac3300) + val colorOrange1100 = Color(0xff9b2200) + val colorOrange1200 = Color(0xff850000) + val colorOrange1300 = Color(0xff620000) + val colorOrange1400 = Color(0xff450000) + val colorOrange200 = Color(0xfffff6ef) + val colorOrange300 = Color(0xffffefe4) + val colorOrange400 = Color(0xffffdfc8) + val colorOrange500 = Color(0xffffc8a1) + val colorOrange600 = Color(0xfffdb37c) + val colorOrange700 = Color(0xfff89440) + val colorOrange800 = Color(0xffdc6700) + val colorOrange900 = Color(0xffbc4500) + val colorPink100 = Color(0xfffffafb) + val colorPink1000 = Color(0xffb80a5b) + val colorPink1100 = Color(0xff9f0850) + val colorPink1200 = Color(0xff7e0642) + val colorPink1300 = Color(0xff5f002b) + val colorPink1400 = Color(0xff430017) + val colorPink200 = Color(0xfffff5f7) + val colorPink300 = Color(0xffffecf0) + val colorPink400 = Color(0xffffdee5) + val colorPink500 = Color(0xffffc2cf) + val colorPink600 = Color(0xffffadc0) + val colorPink700 = Color(0xffff88a6) + val colorPink800 = Color(0xfff7407d) + val colorPink900 = Color(0xffd20c65) + val colorPurple100 = Color(0xfffbfbff) + val colorPurple1000 = Color(0xff6b37de) + val colorPurple1100 = Color(0xff5d26cd) + val colorPurple1200 = Color(0xff4c05b5) + val colorPurple1300 = Color(0xff33008d) + val colorPurple1400 = Color(0xff200066) + val colorPurple200 = Color(0xfff8f7ff) + val colorPurple300 = Color(0xfff1efff) + val colorPurple400 = Color(0xffe6e2ff) + val colorPurple500 = Color(0xffd4cdff) + val colorPurple600 = Color(0xffc5bbff) + val colorPurple700 = Color(0xffb1a0ff) + val colorPurple800 = Color(0xff9271fd) + val colorPurple900 = Color(0xff7a47f1) + val colorRed100 = Color(0xfffffaf9) + val colorRed1000 = Color(0xffbc0f22) + val colorRed1100 = Color(0xffa4041d) + val colorRed1200 = Color(0xff850006) + val colorRed1300 = Color(0xff620000) + val colorRed1400 = Color(0xff450000) + val colorRed200 = Color(0xfffff7f6) + val colorRed300 = Color(0xffffefec) + val colorRed400 = Color(0xffffdfda) + val colorRed500 = Color(0xffffc5bc) + val colorRed600 = Color(0xffffafa5) + val colorRed700 = Color(0xffff8c81) + val colorRed800 = Color(0xffff3d3d) + val colorRed900 = Color(0xffd51928) + val colorThemeBg = Color(0xffffffff) + val colorTransparent = Color(0x00000000) + val colorYellow100 = Color(0xfffffcf0) + val colorYellow1000 = Color(0xff8f4d00) + val colorYellow1100 = Color(0xff803f00) + val colorYellow1200 = Color(0xff692e00) + val colorYellow1300 = Color(0xff541a00) + val colorYellow1400 = Color(0xff410600) + val colorYellow200 = Color(0xfffff8e0) + val colorYellow300 = Color(0xfffff2c1) + val colorYellow400 = Color(0xffffe484) + val colorYellow500 = Color(0xfffbce00) + val colorYellow600 = Color(0xfff1bd00) + val colorYellow700 = Color(0xffdea200) + val colorYellow800 = Color(0xffbe7a00) + val colorYellow900 = Color(0xff9f5b00) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt new file mode 100644 index 0000000000..86624bb597 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt @@ -0,0 +1,335 @@ +/* + * 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. + */ + +/** + * !!! WARNING !!! + * + * THIS IS AN AUTOGENERATED FILE. + * DO NOT EDIT MANUALLY. + */ + + + +@file:Suppress("all") +package io.element.android.compound.tokens.generated.internal + +import androidx.compose.ui.graphics.Color +import io.element.android.compound.annotations.CoreColorToken + +@CoreColorToken +object LightHcColorTokens { + val colorAlphaBlue100 = Color(0x0d2474ff) + val colorAlphaBlue1000 = Color(0xfc023997) + val colorAlphaBlue1100 = Color(0xfc012e89) + val colorAlphaBlue1200 = Color(0xfc00257a) + val colorAlphaBlue1300 = Color(0xff00156b) + val colorAlphaBlue1400 = Color(0xff000b61) + val colorAlphaBlue200 = Color(0x170a70ff) + val colorAlphaBlue300 = Color(0x290b6af9) + val colorAlphaBlue400 = Color(0x380565f5) + val colorAlphaBlue500 = Color(0x5e0663ef) + val colorAlphaBlue600 = Color(0x820264ed) + val colorAlphaBlue700 = Color(0xb50062eb) + val colorAlphaBlue800 = Color(0xfc016ee9) + val colorAlphaBlue900 = Color(0xfc0241a7) + val colorAlphaCyan100 = Color(0x0f16abbb) + val colorAlphaCyan1000 = Color(0xff00437a) + val colorAlphaCyan1100 = Color(0xff003870) + val colorAlphaCyan1200 = Color(0xff003066) + val colorAlphaCyan1300 = Color(0xff001e52) + val colorAlphaCyan1400 = Color(0xff00174d) + val colorAlphaCyan200 = Color(0x1c00a8c2) + val colorAlphaCyan300 = Color(0x3800aabd) + val colorAlphaCyan400 = Color(0x4f03a9bf) + val colorAlphaCyan500 = Color(0x8a01aac1) + val colorAlphaCyan600 = Color(0xeb01b7cb) + val colorAlphaCyan700 = Color(0xff0098c2) + val colorAlphaCyan800 = Color(0xff007ab3) + val colorAlphaCyan900 = Color(0xff004d85) + val colorAlphaFuchsia100 = Color(0x0ab505cc) + val colorAlphaFuchsia1000 = Color(0xe85e007a) + val colorAlphaFuchsia1100 = Color(0xf253026f) + val colorAlphaFuchsia1200 = Color(0xff53026e) + val colorAlphaFuchsia1300 = Color(0xff3a0052) + val colorAlphaFuchsia1400 = Color(0xff34004d) + val colorAlphaFuchsia200 = Color(0x12b60cc6) + val colorAlphaFuchsia300 = Color(0x21bd09c3) + val colorAlphaFuchsia400 = Color(0x2eb105bd) + val colorAlphaFuchsia500 = Color(0x4fb207bb) + val colorAlphaFuchsia600 = Color(0x6eaa04b9) + val colorAlphaFuchsia700 = Color(0x99ab03ba) + val colorAlphaFuchsia800 = Color(0xc9a402b6) + val colorAlphaFuchsia900 = Color(0xe66a0387) + val colorAlphaGray100 = Color(0x0a366881) + val colorAlphaGray1000 = Color(0xc202060d) + val colorAlphaGray1100 = Color(0xcc03060c) + val colorAlphaGray1200 = Color(0xd4020509) + val colorAlphaGray1300 = Color(0xe000040a) + val colorAlphaGray1400 = Color(0xe6010309) + val colorAlphaGray200 = Color(0x0f052657) + val colorAlphaGray300 = Color(0x1f052e61) + val colorAlphaGray400 = Color(0x29052551) + val colorAlphaGray500 = Color(0x42011d3c) + val colorAlphaGray600 = Color(0x59011532) + val colorAlphaGray700 = Color(0x7a05152e) + val colorAlphaGray800 = Color(0x94020e22) + val colorAlphaGray900 = Color(0xba030711) + val colorAlphaGreen100 = Color(0x0f16bb69) + val colorAlphaGreen1000 = Color(0xff004d36) + val colorAlphaGreen1100 = Color(0xff00422c) + val colorAlphaGreen1200 = Color(0xff003824) + val colorAlphaGreen1300 = Color(0xff002916) + val colorAlphaGreen1400 = Color(0xff002410) + val colorAlphaGreen200 = Color(0x1c00b85c) + val colorAlphaGreen300 = Color(0x3b07b661) + val colorAlphaGreen400 = Color(0x5205b867) + val colorAlphaGreen500 = Color(0x8f01b76e) + val colorAlphaGreen600 = Color(0xf501c18a) + val colorAlphaGreen700 = Color(0xff00a37d) + val colorAlphaGreen800 = Color(0xff00856a) + val colorAlphaGreen900 = Color(0xff00573e) + val colorAlphaLime100 = Color(0x1238d40c) + val colorAlphaLime1000 = Color(0xff005200) + val colorAlphaLime1100 = Color(0xff004200) + val colorAlphaLime1200 = Color(0xff003800) + val colorAlphaLime1300 = Color(0xff002900) + val colorAlphaLime1400 = Color(0xff002400) + val colorAlphaLime200 = Color(0x262ecf02) + val colorAlphaLime300 = Color(0x473ace09) + val colorAlphaLime400 = Color(0x6637cc05) + val colorAlphaLime500 = Color(0xb540ce03) + val colorAlphaLime600 = Color(0xdb39bd00) + val colorAlphaLime700 = Color(0xe6249801) + val colorAlphaLime800 = Color(0xf2127e02) + val colorAlphaLime900 = Color(0xff005700) + val colorAlphaOrange100 = Color(0x12ff7d1a) + val colorAlphaOrange1000 = Color(0xff8a0900) + val colorAlphaOrange1100 = Color(0xff750000) + val colorAlphaOrange1200 = Color(0xff660000) + val colorAlphaOrange1300 = Color(0xff4d0000) + val colorAlphaOrange1400 = Color(0xff420000) + val colorAlphaOrange200 = Color(0x1cff6c0a) + val colorAlphaOrange300 = Color(0x38ff6d05) + val colorAlphaOrange400 = Color(0x4dff700a) + val colorAlphaOrange500 = Color(0x85fc6f03) + val colorAlphaOrange600 = Color(0xbff56e00) + val colorAlphaOrange700 = Color(0xffe06c00) + val colorAlphaOrange800 = Color(0xffc24e00) + val colorAlphaOrange900 = Color(0xff941600) + val colorAlphaPink100 = Color(0x0aff0537) + val colorAlphaPink1000 = Color(0xfa830242) + val colorAlphaPink1100 = Color(0xff70003a) + val colorAlphaPink1200 = Color(0xff660030) + val colorAlphaPink1300 = Color(0xff4d001d) + val colorAlphaPink1400 = Color(0xff420015) + val colorAlphaPink200 = Color(0x14ff1447) + val colorAlphaPink300 = Color(0x21ff0037) + val colorAlphaPink400 = Color(0x30ff0a3f) + val colorAlphaPink500 = Color(0x54ff053f) + val colorAlphaPink600 = Color(0x78ff0040) + val colorAlphaPink700 = Color(0xb3f70250) + val colorAlphaPink800 = Color(0xf5de0265) + val colorAlphaPink900 = Color(0xf78f0045) + val colorAlphaPurple100 = Color(0x0a5338ff) + val colorAlphaPurple1000 = Color(0xf24600b8) + val colorAlphaPurple1100 = Color(0xff4300a8) + val colorAlphaPurple1200 = Color(0xff360094) + val colorAlphaPurple1300 = Color(0xff240070) + val colorAlphaPurple1400 = Color(0xff1f0061) + val colorAlphaPurple200 = Color(0x12381aff) + val colorAlphaPurple300 = Color(0x1f2f0fff) + val colorAlphaPurple400 = Color(0x292b0aff) + val colorAlphaPurple500 = Color(0x452b05ff) + val colorAlphaPurple600 = Color(0x613305ff) + val colorAlphaPurple700 = Color(0x873c00ff) + val colorAlphaPurple800 = Color(0xb34c02f7) + val colorAlphaPurple900 = Color(0xe64503bf) + val colorAlphaRed100 = Color(0x0aff391f) + val colorAlphaRed1000 = Color(0xff8a000b) + val colorAlphaRed1100 = Color(0xff750000) + val colorAlphaRed1200 = Color(0xff660000) + val colorAlphaRed1300 = Color(0xff4d0000) + val colorAlphaRed1400 = Color(0xff420000) + val colorAlphaRed200 = Color(0x14ff3814) + val colorAlphaRed300 = Color(0x26ff2b0a) + val colorAlphaRed400 = Color(0x36ff2605) + val colorAlphaRed500 = Color(0x5cff2205) + val colorAlphaRed600 = Color(0x80ff1a05) + val colorAlphaRed700 = Color(0xb8ff0900) + val colorAlphaRed800 = Color(0xe3de0211) + val colorAlphaRed900 = Color(0xff99001a) + val colorAlphaYellow100 = Color(0x21ffc70f) + val colorAlphaYellow1000 = Color(0xff703200) + val colorAlphaYellow1100 = Color(0xff612700) + val colorAlphaYellow1200 = Color(0xff571d00) + val colorAlphaYellow1300 = Color(0xff470c00) + val colorAlphaYellow1400 = Color(0xff3d0500) + val colorAlphaYellow200 = Color(0x40ffc905) + val colorAlphaYellow300 = Color(0x7dffc905) + val colorAlphaYellow400 = Color(0xb8ffcc00) + val colorAlphaYellow500 = Color(0xfff0bc00) + val colorAlphaYellow600 = Color(0xffe0a500) + val colorAlphaYellow700 = Color(0xffc28100) + val colorAlphaYellow800 = Color(0xffa86500) + val colorAlphaYellow900 = Color(0xff753700) + val colorBlue100 = Color(0xfff4f8ff) + val colorBlue1000 = Color(0xff053b9a) + val colorBlue1100 = Color(0xff043088) + val colorBlue1200 = Color(0xff03277b) + val colorBlue1300 = Color(0xff001569) + val colorBlue1400 = Color(0xff000c63) + val colorBlue200 = Color(0xffe9f2ff) + val colorBlue300 = Color(0xffd8e7fe) + val colorBlue400 = Color(0xffc8ddfd) + val colorBlue500 = Color(0xffa3c6fa) + val colorBlue600 = Color(0xff7eaff6) + val colorBlue700 = Color(0xff4a8ef0) + val colorBlue800 = Color(0xff046ee8) + val colorBlue900 = Color(0xff0543a7) + val colorCyan100 = Color(0xfff1fafb) + val colorCyan1000 = Color(0xff00447b) + val colorCyan1100 = Color(0xff00376e) + val colorCyan1200 = Color(0xff002e64) + val colorCyan1300 = Color(0xff001e53) + val colorCyan1400 = Color(0xff00174d) + val colorCyan200 = Color(0xffe3f5f8) + val colorCyan300 = Color(0xffc7ecf0) + val colorCyan400 = Color(0xffb1e4eb) + val colorCyan500 = Color(0xff76d1dd) + val colorCyan600 = Color(0xff15becf) + val colorCyan700 = Color(0xff009ac3) + val colorCyan800 = Color(0xff007ab3) + val colorCyan900 = Color(0xff004c84) + val colorFuchsia100 = Color(0xfffcf5fd) + val colorFuchsia1000 = Color(0xff6c1785) + val colorFuchsia1100 = Color(0xff5c0f76) + val colorFuchsia1200 = Color(0xff52026c) + val colorFuchsia1300 = Color(0xff3b0053) + val colorFuchsia1400 = Color(0xff32004a) + val colorFuchsia200 = Color(0xfffaeefb) + val colorFuchsia300 = Color(0xfff6dff7) + val colorFuchsia400 = Color(0xfff1d2f3) + val colorFuchsia500 = Color(0xffe7b2ea) + val colorFuchsia600 = Color(0xffdb93e1) + val colorFuchsia700 = Color(0xffcb68d4) + val colorFuchsia800 = Color(0xffb937c6) + val colorFuchsia900 = Color(0xff781c90) + val colorGray100 = Color(0xfff7f9fa) + val colorGray1000 = Color(0xff3f4248) + val colorGray1100 = Color(0xff35383d) + val colorGray1200 = Color(0xff2d3034) + val colorGray1300 = Color(0xff1f2126) + val colorGray1400 = Color(0xff1a1c21) + val colorGray200 = Color(0xfff0f2f5) + val colorGray300 = Color(0xffe1e6ec) + val colorGray400 = Color(0xffd7dce3) + val colorGray500 = Color(0xffbdc4cc) + val colorGray600 = Color(0xffa6adb7) + val colorGray700 = Color(0xff878f9b) + val colorGray800 = Color(0xff6c737e) + val colorGray900 = Color(0xff474a51) + val colorGreen100 = Color(0xfff1fbf6) + val colorGreen1000 = Color(0xff004d36) + val colorGreen1100 = Color(0xff00402b) + val colorGreen1200 = Color(0xff003723) + val colorGreen1300 = Color(0xff002715) + val colorGreen1400 = Color(0xff00210f) + val colorGreen200 = Color(0xffe3f7ed) + val colorGreen300 = Color(0xffc6eedb) + val colorGreen400 = Color(0xffafe8ce) + val colorGreen500 = Color(0xff71d7ae) + val colorGreen600 = Color(0xff0bc491) + val colorGreen700 = Color(0xff00a27c) + val colorGreen800 = Color(0xff008268) + val colorGreen900 = Color(0xff00553d) + val colorLime100 = Color(0xfff1fcee) + val colorLime1000 = Color(0xff004f00) + val colorLime1100 = Color(0xff004200) + val colorLime1200 = Color(0xff003900) + val colorLime1300 = Color(0xff002900) + val colorLime1400 = Color(0xff002200) + val colorLime200 = Color(0xffe0f8d9) + val colorLime300 = Color(0xffc8f1ba) + val colorLime400 = Color(0xffafeb9b) + val colorLime500 = Color(0xff76db4c) + val colorLime600 = Color(0xff54c424) + val colorLime700 = Color(0xff3aa31a) + val colorLime800 = Color(0xff1f850f) + val colorLime900 = Color(0xff005700) + val colorOrange100 = Color(0xfffff6ef) + val colorOrange1000 = Color(0xff890800) + val colorOrange1100 = Color(0xff770000) + val colorOrange1200 = Color(0xff670000) + val colorOrange1300 = Color(0xff4c0000) + val colorOrange1400 = Color(0xff420000) + val colorOrange200 = Color(0xffffefe4) + val colorOrange300 = Color(0xffffdfc8) + val colorOrange400 = Color(0xffffd4b5) + val colorOrange500 = Color(0xfffdb37c) + val colorOrange600 = Color(0xfff89440) + val colorOrange700 = Color(0xffe26e00) + val colorOrange800 = Color(0xffc44d00) + val colorOrange900 = Color(0xff931700) + val colorPink100 = Color(0xfffff5f7) + val colorPink1000 = Color(0xff840745) + val colorPink1100 = Color(0xff72003a) + val colorPink1200 = Color(0xff64002f) + val colorPink1300 = Color(0xff4a001c) + val colorPink1400 = Color(0xff410015) + val colorPink200 = Color(0xffffecf0) + val colorPink300 = Color(0xffffdee5) + val colorPink400 = Color(0xffffd0da) + val colorPink500 = Color(0xffffadc0) + val colorPink600 = Color(0xffff88a6) + val colorPink700 = Color(0xfff94e84) + val colorPink800 = Color(0xffe00c6a) + val colorPink900 = Color(0xff92084b) + val colorPurple100 = Color(0xfff8f7ff) + val colorPurple1000 = Color(0xff4f0dba) + val colorPurple1100 = Color(0xff4200a6) + val colorPurple1200 = Color(0xff360094) + val colorPurple1300 = Color(0xff240070) + val colorPurple1400 = Color(0xff1f0062) + val colorPurple200 = Color(0xfff1efff) + val colorPurple300 = Color(0xffe6e2ff) + val colorPurple400 = Color(0xffddd8ff) + val colorPurple500 = Color(0xffc5bbff) + val colorPurple600 = Color(0xffb1a0ff) + val colorPurple700 = Color(0xff9778fe) + val colorPurple800 = Color(0xff824ef9) + val colorPurple900 = Color(0xff571cc4) + val colorRed100 = Color(0xfffff7f6) + val colorRed1000 = Color(0xff8b000c) + val colorRed1100 = Color(0xff770000) + val colorRed1200 = Color(0xff670000) + val colorRed1300 = Color(0xff4c0000) + val colorRed1400 = Color(0xff420000) + val colorRed200 = Color(0xffffefec) + val colorRed300 = Color(0xffffdfda) + val colorRed400 = Color(0xffffd1ca) + val colorRed500 = Color(0xffffafa5) + val colorRed600 = Color(0xffff8c81) + val colorRed700 = Color(0xffff4e49) + val colorRed800 = Color(0xffe11e2a) + val colorRed900 = Color(0xff99001a) + val colorThemeBg = Color(0xffffffff) + val colorTransparent = Color(0x00000000) + val colorYellow100 = Color(0xfffff8e0) + val colorYellow1000 = Color(0xff6e3100) + val colorYellow1100 = Color(0xff612600) + val colorYellow1200 = Color(0xff571d00) + val colorYellow1300 = Color(0xff450c00) + val colorYellow1400 = Color(0xff3f0500) + val colorYellow200 = Color(0xfffff2c1) + val colorYellow300 = Color(0xffffe484) + val colorYellow400 = Color(0xffffda49) + val colorYellow500 = Color(0xfff1bd00) + val colorYellow600 = Color(0xffdea200) + val colorYellow700 = Color(0xffc38100) + val colorYellow800 = Color(0xffa76300) + val colorYellow900 = Color(0xff773800) +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/utils/ColorUtils.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/utils/ColorUtils.kt new file mode 100644 index 0000000000..f0c6c12fb0 --- /dev/null +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/utils/ColorUtils.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2023, 2024 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.compound.utils + +import androidx.compose.ui.graphics.Color + +/** + * Convert color to Human Readable Format. + */ +fun Color.toHrf(): String { + return "0x" + value.toString(16).take(8).uppercase() +} diff --git a/libraries/compound/src/main/res/drawable/ic_compound_admin.xml b/libraries/compound/src/main/res/drawable/ic_compound_admin.xml new file mode 100644 index 0000000000..8762195e7f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_admin.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_arrow_down.xml b/libraries/compound/src/main/res/drawable/ic_compound_arrow_down.xml new file mode 100644 index 0000000000..6d311ac7a2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_arrow_down.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_arrow_left.xml b/libraries/compound/src/main/res/drawable/ic_compound_arrow_left.xml new file mode 100644 index 0000000000..4e1949895f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_arrow_left.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_arrow_right.xml b/libraries/compound/src/main/res/drawable/ic_compound_arrow_right.xml new file mode 100644 index 0000000000..4a42e3c16f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_arrow_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_arrow_up.xml b/libraries/compound/src/main/res/drawable/ic_compound_arrow_up.xml new file mode 100644 index 0000000000..7ff26b539a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_arrow_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_arrow_up_right.xml b/libraries/compound/src/main/res/drawable/ic_compound_arrow_up_right.xml new file mode 100644 index 0000000000..ea686b6cff --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_arrow_up_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join.xml b/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join.xml new file mode 100644 index 0000000000..2c2f779ab6 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join_solid.xml new file mode 100644 index 0000000000..1346e2c889 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_ask_to_join_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_attachment.xml b/libraries/compound/src/main/res/drawable/ic_compound_attachment.xml new file mode 100644 index 0000000000..4ddf7f4df7 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_attachment.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_audio.xml b/libraries/compound/src/main/res/drawable/ic_compound_audio.xml new file mode 100644 index 0000000000..5fb9365470 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_audio.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_block.xml b/libraries/compound/src/main/res/drawable/ic_compound_block.xml new file mode 100644 index 0000000000..08ef51dce3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_block.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_bold.xml b/libraries/compound/src/main/res/drawable/ic_compound_bold.xml new file mode 100644 index 0000000000..2546a230cc --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_bold.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_calendar.xml b/libraries/compound/src/main/res/drawable/ic_compound_calendar.xml new file mode 100644 index 0000000000..72a9fe5868 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_calendar.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chart.xml b/libraries/compound/src/main/res/drawable/ic_compound_chart.xml new file mode 100644 index 0000000000..cc1c8fb662 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chart.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chat.xml b/libraries/compound/src/main/res/drawable/ic_compound_chat.xml new file mode 100644 index 0000000000..3a7e70841b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chat.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chat_new.xml b/libraries/compound/src/main/res/drawable/ic_compound_chat_new.xml new file mode 100644 index 0000000000..8bf9f6762f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chat_new.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chat_problem.xml b/libraries/compound/src/main/res/drawable/ic_compound_chat_problem.xml new file mode 100644 index 0000000000..380358478a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chat_problem.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chat_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_chat_solid.xml new file mode 100644 index 0000000000..d08def35fe --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chat_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_check.xml b/libraries/compound/src/main/res/drawable/ic_compound_check.xml new file mode 100644 index 0000000000..78f935c940 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_check.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_check_circle.xml b/libraries/compound/src/main/res/drawable/ic_compound_check_circle.xml new file mode 100644 index 0000000000..8d6147246b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_check_circle.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_check_circle_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_check_circle_solid.xml new file mode 100644 index 0000000000..d258a5c97a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_check_circle_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chevron_down.xml b/libraries/compound/src/main/res/drawable/ic_compound_chevron_down.xml new file mode 100644 index 0000000000..2ac456e988 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chevron_down.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chevron_left.xml b/libraries/compound/src/main/res/drawable/ic_compound_chevron_left.xml new file mode 100644 index 0000000000..50316a4e81 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chevron_left.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chevron_right.xml b/libraries/compound/src/main/res/drawable/ic_compound_chevron_right.xml new file mode 100644 index 0000000000..d19a9daa4d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chevron_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chevron_up.xml b/libraries/compound/src/main/res/drawable/ic_compound_chevron_up.xml new file mode 100644 index 0000000000..d84ebade9c --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chevron_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_chevron_up_down.xml b/libraries/compound/src/main/res/drawable/ic_compound_chevron_up_down.xml new file mode 100644 index 0000000000..213dfbef9f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_chevron_up_down.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_circle.xml b/libraries/compound/src/main/res/drawable/ic_compound_circle.xml new file mode 100644 index 0000000000..d5a292aa3c --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_circle.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_close.xml b/libraries/compound/src/main/res/drawable/ic_compound_close.xml new file mode 100644 index 0000000000..ef8a75f08a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_cloud.xml b/libraries/compound/src/main/res/drawable/ic_compound_cloud.xml new file mode 100644 index 0000000000..b96fd18250 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_cloud.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_cloud_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_cloud_solid.xml new file mode 100644 index 0000000000..09a91809f3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_cloud_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_code.xml b/libraries/compound/src/main/res/drawable/ic_compound_code.xml new file mode 100644 index 0000000000..c17c73c201 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_code.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_collapse.xml b/libraries/compound/src/main/res/drawable/ic_compound_collapse.xml new file mode 100644 index 0000000000..8cc9302197 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_collapse.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_company.xml b/libraries/compound/src/main/res/drawable/ic_compound_company.xml new file mode 100644 index 0000000000..28a9232c13 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_company.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_compose.xml b/libraries/compound/src/main/res/drawable/ic_compound_compose.xml new file mode 100644 index 0000000000..eaa9ca0ef1 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_compose.xml @@ -0,0 +1,14 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_computer.xml b/libraries/compound/src/main/res/drawable/ic_compound_computer.xml new file mode 100644 index 0000000000..97748e8ffd --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_computer.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_copy.xml b/libraries/compound/src/main/res/drawable/ic_compound_copy.xml new file mode 100644 index 0000000000..4492c5aca9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_copy.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_dark_mode.xml b/libraries/compound/src/main/res/drawable/ic_compound_dark_mode.xml new file mode 100644 index 0000000000..bc4fa89cd4 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_dark_mode.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_delete.xml b/libraries/compound/src/main/res/drawable/ic_compound_delete.xml new file mode 100644 index 0000000000..dd2e3b50d0 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_delete.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_devices.xml b/libraries/compound/src/main/res/drawable/ic_compound_devices.xml new file mode 100644 index 0000000000..a399d675cf --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_devices.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_dial_pad.xml b/libraries/compound/src/main/res/drawable/ic_compound_dial_pad.xml new file mode 100644 index 0000000000..1967b8df77 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_dial_pad.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_document.xml b/libraries/compound/src/main/res/drawable/ic_compound_document.xml new file mode 100644 index 0000000000..830a36597a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_document.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_download.xml b/libraries/compound/src/main/res/drawable/ic_compound_download.xml new file mode 100644 index 0000000000..bf4c24ec26 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_download.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_download_ios.xml b/libraries/compound/src/main/res/drawable/ic_compound_download_ios.xml new file mode 100644 index 0000000000..16a45ee188 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_download_ios.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_drag_grid.xml b/libraries/compound/src/main/res/drawable/ic_compound_drag_grid.xml new file mode 100644 index 0000000000..96697b574d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_drag_grid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_drag_list.xml b/libraries/compound/src/main/res/drawable/ic_compound_drag_list.xml new file mode 100644 index 0000000000..57fe86c0e8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_drag_list.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_earpiece.xml b/libraries/compound/src/main/res/drawable/ic_compound_earpiece.xml new file mode 100644 index 0000000000..66b495b304 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_earpiece.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_edit.xml b/libraries/compound/src/main/res/drawable/ic_compound_edit.xml new file mode 100644 index 0000000000..de0c0b345a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_edit.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_edit_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_edit_solid.xml new file mode 100644 index 0000000000..33da283f4d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_edit_solid.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_email.xml b/libraries/compound/src/main/res/drawable/ic_compound_email.xml new file mode 100644 index 0000000000..223c9620f3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_email.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_email_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_email_solid.xml new file mode 100644 index 0000000000..f5c98f8cfa --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_email_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_end_call.xml b/libraries/compound/src/main/res/drawable/ic_compound_end_call.xml new file mode 100644 index 0000000000..f58a645c6e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_end_call.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_error.xml b/libraries/compound/src/main/res/drawable/ic_compound_error.xml new file mode 100644 index 0000000000..a4ea2f0016 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_error.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_error_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_error_solid.xml new file mode 100644 index 0000000000..97b8ece183 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_error_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_expand.xml b/libraries/compound/src/main/res/drawable/ic_compound_expand.xml new file mode 100644 index 0000000000..88aef8abc1 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_expand.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_explore.xml b/libraries/compound/src/main/res/drawable/ic_compound_explore.xml new file mode 100644 index 0000000000..9b62efa291 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_explore.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_export_archive.xml b/libraries/compound/src/main/res/drawable/ic_compound_export_archive.xml new file mode 100644 index 0000000000..f09775d0be --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_export_archive.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_extensions.xml b/libraries/compound/src/main/res/drawable/ic_compound_extensions.xml new file mode 100644 index 0000000000..1bd8ae7bce --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_extensions.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_extensions_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_extensions_solid.xml new file mode 100644 index 0000000000..7873a49ed6 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_extensions_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_favourite.xml b/libraries/compound/src/main/res/drawable/ic_compound_favourite.xml new file mode 100644 index 0000000000..f7845dc080 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_favourite.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_favourite_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_favourite_solid.xml new file mode 100644 index 0000000000..3fc393c572 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_favourite_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_file_error.xml b/libraries/compound/src/main/res/drawable/ic_compound_file_error.xml new file mode 100644 index 0000000000..13b3571ef8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_file_error.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_files.xml b/libraries/compound/src/main/res/drawable/ic_compound_files.xml new file mode 100644 index 0000000000..67a30b6bd8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_files.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_filter.xml b/libraries/compound/src/main/res/drawable/ic_compound_filter.xml new file mode 100644 index 0000000000..2f2b0e5f10 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_filter.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_forward.xml b/libraries/compound/src/main/res/drawable/ic_compound_forward.xml new file mode 100644 index 0000000000..e614fabb4e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_forward.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_grid.xml b/libraries/compound/src/main/res/drawable/ic_compound_grid.xml new file mode 100644 index 0000000000..223ed40a2f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_grid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_group.xml b/libraries/compound/src/main/res/drawable/ic_compound_group.xml new file mode 100644 index 0000000000..4781d1306b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_group.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_guest.xml b/libraries/compound/src/main/res/drawable/ic_compound_guest.xml new file mode 100644 index 0000000000..1bb2d99842 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_guest.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_headphones_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_headphones_off_solid.xml new file mode 100644 index 0000000000..af81d29c1d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_headphones_off_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_headphones_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_headphones_solid.xml new file mode 100644 index 0000000000..eac3a666d0 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_headphones_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_help.xml b/libraries/compound/src/main/res/drawable/ic_compound_help.xml new file mode 100644 index 0000000000..293120e8cd --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_help.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_help_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_help_solid.xml new file mode 100644 index 0000000000..80332718c2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_help_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_history.xml b/libraries/compound/src/main/res/drawable/ic_compound_history.xml new file mode 100644 index 0000000000..25d4c68509 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_history.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_home.xml b/libraries/compound/src/main/res/drawable/ic_compound_home.xml new file mode 100644 index 0000000000..0feb167199 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_home.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_home_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_home_solid.xml new file mode 100644 index 0000000000..10cca67a37 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_home_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_host.xml b/libraries/compound/src/main/res/drawable/ic_compound_host.xml new file mode 100644 index 0000000000..d45d1c0278 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_host.xml @@ -0,0 +1,14 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_image.xml b/libraries/compound/src/main/res/drawable/ic_compound_image.xml new file mode 100644 index 0000000000..58a3525b3a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_image.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_image_error.xml b/libraries/compound/src/main/res/drawable/ic_compound_image_error.xml new file mode 100644 index 0000000000..1c8d716166 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_image_error.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_indent_decrease.xml b/libraries/compound/src/main/res/drawable/ic_compound_indent_decrease.xml new file mode 100644 index 0000000000..5ada985743 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_indent_decrease.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_indent_increase.xml b/libraries/compound/src/main/res/drawable/ic_compound_indent_increase.xml new file mode 100644 index 0000000000..de5df3977a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_indent_increase.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_info.xml b/libraries/compound/src/main/res/drawable/ic_compound_info.xml new file mode 100644 index 0000000000..cf0318bb61 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_info.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_info_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_info_solid.xml new file mode 100644 index 0000000000..9101aacffc --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_info_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_inline_code.xml b/libraries/compound/src/main/res/drawable/ic_compound_inline_code.xml new file mode 100644 index 0000000000..9f78e1f8c2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_inline_code.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_italic.xml b/libraries/compound/src/main/res/drawable/ic_compound_italic.xml new file mode 100644 index 0000000000..e3fee1f82e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_italic.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_key.xml b/libraries/compound/src/main/res/drawable/ic_compound_key.xml new file mode 100644 index 0000000000..112c16d78f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_key.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_key_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_key_off.xml new file mode 100644 index 0000000000..b160e81c73 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_key_off.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_key_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_key_off_solid.xml new file mode 100644 index 0000000000..c1961ec390 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_key_off_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_key_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_key_solid.xml new file mode 100644 index 0000000000..29f9ad1a42 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_key_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_keyboard.xml b/libraries/compound/src/main/res/drawable/ic_compound_keyboard.xml new file mode 100644 index 0000000000..6216c1ccf8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_keyboard.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_labs.xml b/libraries/compound/src/main/res/drawable/ic_compound_labs.xml new file mode 100644 index 0000000000..d0bcae3bab --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_labs.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_leave.xml b/libraries/compound/src/main/res/drawable/ic_compound_leave.xml new file mode 100644 index 0000000000..ad5897d4f2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_leave.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_link.xml b/libraries/compound/src/main/res/drawable/ic_compound_link.xml new file mode 100644 index 0000000000..3787cf3981 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_link.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_linux.xml b/libraries/compound/src/main/res/drawable/ic_compound_linux.xml new file mode 100644 index 0000000000..bb3216e729 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_linux.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_list_bulleted.xml b/libraries/compound/src/main/res/drawable/ic_compound_list_bulleted.xml new file mode 100644 index 0000000000..f7fe7a8256 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_list_bulleted.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_list_numbered.xml b/libraries/compound/src/main/res/drawable/ic_compound_list_numbered.xml new file mode 100644 index 0000000000..d3fbeb2d2d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_list_numbered.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_list_view.xml b/libraries/compound/src/main/res/drawable/ic_compound_list_view.xml new file mode 100644 index 0000000000..ffd3359cfa --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_list_view.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_location_navigator.xml b/libraries/compound/src/main/res/drawable/ic_compound_location_navigator.xml new file mode 100644 index 0000000000..bffa2d9f9d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_location_navigator.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_location_navigator_centred.xml b/libraries/compound/src/main/res/drawable/ic_compound_location_navigator_centred.xml new file mode 100644 index 0000000000..50f8ac655d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_location_navigator_centred.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_location_pin.xml b/libraries/compound/src/main/res/drawable/ic_compound_location_pin.xml new file mode 100644 index 0000000000..063076d4ae --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_location_pin.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_location_pin_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_location_pin_solid.xml new file mode 100644 index 0000000000..defb2d4e42 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_location_pin_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_lock.xml b/libraries/compound/src/main/res/drawable/ic_compound_lock.xml new file mode 100644 index 0000000000..9715295d94 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_lock.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_lock_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_lock_off.xml new file mode 100644 index 0000000000..a19bac4811 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_lock_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_lock_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_lock_solid.xml new file mode 100644 index 0000000000..6a5a11b4de --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_lock_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mac.xml b/libraries/compound/src/main/res/drawable/ic_compound_mac.xml new file mode 100644 index 0000000000..6f72038f43 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mac.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mark_as_read.xml b/libraries/compound/src/main/res/drawable/ic_compound_mark_as_read.xml new file mode 100644 index 0000000000..8de67ac4e8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mark_as_read.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mark_as_unread.xml b/libraries/compound/src/main/res/drawable/ic_compound_mark_as_unread.xml new file mode 100644 index 0000000000..6b3c53144a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mark_as_unread.xml @@ -0,0 +1,14 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mark_threads_as_read.xml b/libraries/compound/src/main/res/drawable/ic_compound_mark_threads_as_read.xml new file mode 100644 index 0000000000..5d6c12a557 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mark_threads_as_read.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_marker_read_receipts.xml b/libraries/compound/src/main/res/drawable/ic_compound_marker_read_receipts.xml new file mode 100644 index 0000000000..c70cfd3e51 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_marker_read_receipts.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mention.xml b/libraries/compound/src/main/res/drawable/ic_compound_mention.xml new file mode 100644 index 0000000000..274ccb3775 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mention.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_menu.xml b/libraries/compound/src/main/res/drawable/ic_compound_menu.xml new file mode 100644 index 0000000000..c3ee1a2ee1 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_menu.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mic_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_mic_off.xml new file mode 100644 index 0000000000..e28210c07d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mic_off.xml @@ -0,0 +1,14 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mic_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_mic_off_solid.xml new file mode 100644 index 0000000000..686809342a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mic_off_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mic_on.xml b/libraries/compound/src/main/res/drawable/ic_compound_mic_on.xml new file mode 100644 index 0000000000..793b9c8f83 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mic_on.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mic_on_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_mic_on_solid.xml new file mode 100644 index 0000000000..026f477e75 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mic_on_solid.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_minus.xml b/libraries/compound/src/main/res/drawable/ic_compound_minus.xml new file mode 100644 index 0000000000..064946b6dc --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_minus.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_mobile.xml b/libraries/compound/src/main/res/drawable/ic_compound_mobile.xml new file mode 100644 index 0000000000..8257628868 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_mobile.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_notifications.xml b/libraries/compound/src/main/res/drawable/ic_compound_notifications.xml new file mode 100644 index 0000000000..afd16aa8e9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_notifications.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_notifications_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_notifications_off.xml new file mode 100644 index 0000000000..e4fca897a3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_notifications_off.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_notifications_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_notifications_off_solid.xml new file mode 100644 index 0000000000..4bc9fdd2ab --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_notifications_off_solid.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_notifications_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_notifications_solid.xml new file mode 100644 index 0000000000..358a18c83e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_notifications_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_offline.xml b/libraries/compound/src/main/res/drawable/ic_compound_offline.xml new file mode 100644 index 0000000000..322954e4b0 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_offline.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_overflow_horizontal.xml b/libraries/compound/src/main/res/drawable/ic_compound_overflow_horizontal.xml new file mode 100644 index 0000000000..c85d1e8da2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_overflow_horizontal.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_overflow_vertical.xml b/libraries/compound/src/main/res/drawable/ic_compound_overflow_vertical.xml new file mode 100644 index 0000000000..269e28613c --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_overflow_vertical.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_pause.xml b/libraries/compound/src/main/res/drawable/ic_compound_pause.xml new file mode 100644 index 0000000000..bcd8325107 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_pause.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_pause_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_pause_solid.xml new file mode 100644 index 0000000000..f25a7cbcfc --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_pause_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_pin.xml b/libraries/compound/src/main/res/drawable/ic_compound_pin.xml new file mode 100644 index 0000000000..0aa36f53e9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_pin.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_pin_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_pin_solid.xml new file mode 100644 index 0000000000..9326b0fd75 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_pin_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_play.xml b/libraries/compound/src/main/res/drawable/ic_compound_play.xml new file mode 100644 index 0000000000..d7b8d3c5e5 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_play.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_play_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_play_solid.xml new file mode 100644 index 0000000000..fca650ccd8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_play_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_plus.xml b/libraries/compound/src/main/res/drawable/ic_compound_plus.xml new file mode 100644 index 0000000000..a20a59aac9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_plus.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_polls.xml b/libraries/compound/src/main/res/drawable/ic_compound_polls.xml new file mode 100644 index 0000000000..8c0e2b5a45 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_polls.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_polls_end.xml b/libraries/compound/src/main/res/drawable/ic_compound_polls_end.xml new file mode 100644 index 0000000000..8cfe2be80e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_polls_end.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_pop_out.xml b/libraries/compound/src/main/res/drawable/ic_compound_pop_out.xml new file mode 100644 index 0000000000..7b5b07b969 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_pop_out.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_preferences.xml b/libraries/compound/src/main/res/drawable/ic_compound_preferences.xml new file mode 100644 index 0000000000..fbc271730d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_preferences.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_presence_outline_8_x_8.xml b/libraries/compound/src/main/res/drawable/ic_compound_presence_outline_8_x_8.xml new file mode 100644 index 0000000000..3d815c0696 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_presence_outline_8_x_8.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_presence_solid_8_x_8.xml b/libraries/compound/src/main/res/drawable/ic_compound_presence_solid_8_x_8.xml new file mode 100644 index 0000000000..ab82df2441 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_presence_solid_8_x_8.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_presence_strikethrough_8_x_8.xml b/libraries/compound/src/main/res/drawable/ic_compound_presence_strikethrough_8_x_8.xml new file mode 100644 index 0000000000..1ed8a1e492 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_presence_strikethrough_8_x_8.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_public.xml b/libraries/compound/src/main/res/drawable/ic_compound_public.xml new file mode 100644 index 0000000000..3dfd7046ea --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_public.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_qr_code.xml b/libraries/compound/src/main/res/drawable/ic_compound_qr_code.xml new file mode 100644 index 0000000000..4befbcef95 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_qr_code.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_quote.xml b/libraries/compound/src/main/res/drawable/ic_compound_quote.xml new file mode 100644 index 0000000000..728fe07e43 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_quote.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_raised_hand_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_raised_hand_solid.xml new file mode 100644 index 0000000000..d345569ead --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_raised_hand_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_reaction.xml b/libraries/compound/src/main/res/drawable/ic_compound_reaction.xml new file mode 100644 index 0000000000..f85f57d002 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_reaction.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_reaction_add.xml b/libraries/compound/src/main/res/drawable/ic_compound_reaction_add.xml new file mode 100644 index 0000000000..3fe88d4f8a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_reaction_add.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_reaction_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_reaction_solid.xml new file mode 100644 index 0000000000..826ac69830 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_reaction_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_reply.xml b/libraries/compound/src/main/res/drawable/ic_compound_reply.xml new file mode 100644 index 0000000000..45a797deda --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_reply.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_restart.xml b/libraries/compound/src/main/res/drawable/ic_compound_restart.xml new file mode 100644 index 0000000000..9360979845 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_restart.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_room.xml b/libraries/compound/src/main/res/drawable/ic_compound_room.xml new file mode 100644 index 0000000000..a0a278eab7 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_room.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_search.xml b/libraries/compound/src/main/res/drawable/ic_compound_search.xml new file mode 100644 index 0000000000..8e1ec94374 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_search.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_send.xml b/libraries/compound/src/main/res/drawable/ic_compound_send.xml new file mode 100644 index 0000000000..8c0d5e1159 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_send.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_send_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_send_solid.xml new file mode 100644 index 0000000000..3ac0bc6f62 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_send_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_settings.xml b/libraries/compound/src/main/res/drawable/ic_compound_settings.xml new file mode 100644 index 0000000000..7a79aa33ec --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_settings.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_settings_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_settings_solid.xml new file mode 100644 index 0000000000..7a75b037ba --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_settings_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_share.xml b/libraries/compound/src/main/res/drawable/ic_compound_share.xml new file mode 100644 index 0000000000..6abf169f20 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_share_android.xml b/libraries/compound/src/main/res/drawable/ic_compound_share_android.xml new file mode 100644 index 0000000000..a92b79a76a --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_share_android.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_share_ios.xml b/libraries/compound/src/main/res/drawable/ic_compound_share_ios.xml new file mode 100644 index 0000000000..e481978c28 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_share_ios.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_share_screen.xml b/libraries/compound/src/main/res/drawable/ic_compound_share_screen.xml new file mode 100644 index 0000000000..89f63b897c --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_share_screen.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_share_screen_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_share_screen_solid.xml new file mode 100644 index 0000000000..ee9a1aa837 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_share_screen_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_shield.xml b/libraries/compound/src/main/res/drawable/ic_compound_shield.xml new file mode 100644 index 0000000000..7d2ee79157 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_shield.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_sidebar.xml b/libraries/compound/src/main/res/drawable/ic_compound_sidebar.xml new file mode 100644 index 0000000000..4bd5a0b3e3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_sidebar.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_sign_out.xml b/libraries/compound/src/main/res/drawable/ic_compound_sign_out.xml new file mode 100644 index 0000000000..a6ded2b7a8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_sign_out.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_spinner.xml b/libraries/compound/src/main/res/drawable/ic_compound_spinner.xml new file mode 100644 index 0000000000..80721fdce8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_spinner.xml @@ -0,0 +1,11 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_spotlight.xml b/libraries/compound/src/main/res/drawable/ic_compound_spotlight.xml new file mode 100644 index 0000000000..acaad53b3b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_spotlight.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_spotlight_view.xml b/libraries/compound/src/main/res/drawable/ic_compound_spotlight_view.xml new file mode 100644 index 0000000000..724cdf91cf --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_spotlight_view.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_strikethrough.xml b/libraries/compound/src/main/res/drawable/ic_compound_strikethrough.xml new file mode 100644 index 0000000000..a472c6c97e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_strikethrough.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_switch_camera_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_switch_camera_solid.xml new file mode 100644 index 0000000000..a7695e40ff --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_switch_camera_solid.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_take_photo.xml b/libraries/compound/src/main/res/drawable/ic_compound_take_photo.xml new file mode 100644 index 0000000000..d6dbb4d568 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_take_photo.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_take_photo_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_take_photo_solid.xml new file mode 100644 index 0000000000..2db8a6cdf0 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_take_photo_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_text_formatting.xml b/libraries/compound/src/main/res/drawable/ic_compound_text_formatting.xml new file mode 100644 index 0000000000..4126080fa9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_text_formatting.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_threads.xml b/libraries/compound/src/main/res/drawable/ic_compound_threads.xml new file mode 100644 index 0000000000..4fa1e877d1 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_threads.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml new file mode 100644 index 0000000000..4db292231d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_time.xml b/libraries/compound/src/main/res/drawable/ic_compound_time.xml new file mode 100644 index 0000000000..b29bb29de7 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_time.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_underline.xml b/libraries/compound/src/main/res/drawable/ic_compound_underline.xml new file mode 100644 index 0000000000..c90d6bc591 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_underline.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_unknown.xml b/libraries/compound/src/main/res/drawable/ic_compound_unknown.xml new file mode 100644 index 0000000000..87afe69e02 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_unknown.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_unknown_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_unknown_solid.xml new file mode 100644 index 0000000000..89b6a89056 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_unknown_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_unpin.xml b/libraries/compound/src/main/res/drawable/ic_compound_unpin.xml new file mode 100644 index 0000000000..c7aee251f4 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_unpin.xml @@ -0,0 +1,14 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user.xml b/libraries/compound/src/main/res/drawable/ic_compound_user.xml new file mode 100644 index 0000000000..948bda3e4e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user_add.xml b/libraries/compound/src/main/res/drawable/ic_compound_user_add.xml new file mode 100644 index 0000000000..81d9aaf1bb --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user_add.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user_add_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_user_add_solid.xml new file mode 100644 index 0000000000..693db72c06 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user_add_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user_profile.xml b/libraries/compound/src/main/res/drawable/ic_compound_user_profile.xml new file mode 100644 index 0000000000..222b9510ea --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user_profile.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user_profile_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_user_profile_solid.xml new file mode 100644 index 0000000000..5d268642e0 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user_profile_solid.xml @@ -0,0 +1,12 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_user_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_user_solid.xml new file mode 100644 index 0000000000..c281d6f009 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_user_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_verified.xml b/libraries/compound/src/main/res/drawable/ic_compound_verified.xml new file mode 100644 index 0000000000..f30bec93ff --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_verified.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call.xml new file mode 100644 index 0000000000..4f1c9b1ba7 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call_declined_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call_declined_solid.xml new file mode 100644 index 0000000000..a6b699c6bd --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call_declined_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call_missed_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call_missed_solid.xml new file mode 100644 index 0000000000..57c1502560 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call_missed_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call_off.xml new file mode 100644 index 0000000000..6466ec2848 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call_off_solid.xml new file mode 100644 index 0000000000..35a5796577 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call_off_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_video_call_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_video_call_solid.xml new file mode 100644 index 0000000000..ec4cf0902e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_video_call_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_visibility_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_visibility_off.xml new file mode 100644 index 0000000000..c4234584a3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_visibility_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_visibility_on.xml b/libraries/compound/src/main/res/drawable/ic_compound_visibility_on.xml new file mode 100644 index 0000000000..a66dcfa429 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_visibility_on.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_voice_call.xml b/libraries/compound/src/main/res/drawable/ic_compound_voice_call.xml new file mode 100644 index 0000000000..579738d57b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_voice_call.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_voice_call_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_voice_call_solid.xml new file mode 100644 index 0000000000..428e2fa3d1 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_voice_call_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_volume_off.xml b/libraries/compound/src/main/res/drawable/ic_compound_volume_off.xml new file mode 100644 index 0000000000..e240c01b0b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_volume_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_volume_off_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_volume_off_solid.xml new file mode 100644 index 0000000000..6c801e7a16 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_volume_off_solid.xml @@ -0,0 +1,10 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_volume_on.xml b/libraries/compound/src/main/res/drawable/ic_compound_volume_on.xml new file mode 100644 index 0000000000..453a2578e2 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_volume_on.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_volume_on_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_volume_on_solid.xml new file mode 100644 index 0000000000..232571342f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_volume_on_solid.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_warning.xml b/libraries/compound/src/main/res/drawable/ic_compound_warning.xml new file mode 100644 index 0000000000..53b838ca56 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_warning.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_web_browser.xml b/libraries/compound/src/main/res/drawable/ic_compound_web_browser.xml new file mode 100644 index 0000000000..baaf15c059 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_web_browser.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_windows.xml b/libraries/compound/src/main/res/drawable/ic_compound_windows.xml new file mode 100644 index 0000000000..37a3915dc8 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_windows.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml b/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml new file mode 100644 index 0000000000..3871fde4b4 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml new file mode 100644 index 0000000000..51c5c9f9cb --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/designsystem/build.gradle.kts b/libraries/designsystem/build.gradle.kts index c2eec20b8c..3983317055 100644 --- a/libraries/designsystem/build.gradle.kts +++ b/libraries/designsystem/build.gradle.kts @@ -27,7 +27,7 @@ android { } dependencies { - api(libs.compound) + api(projects.libraries.compound) implementation(libs.androidx.compose.material3.windowsizeclass) implementation(libs.androidx.compose.material3.adaptive) From 6b4198d75b9c6dda851f8e837dad4407e93f0cb0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:25:49 +0200 Subject: [PATCH 37/73] Import Compound scripts from project https://github.com/element-hq/compound-android --- tools/compound/addAutoMirrored.py | 120 ++++++++++++++++++++++++++++++ tools/compound/import_tokens.sh | 38 ++++++++++ 2 files changed, 158 insertions(+) create mode 100644 tools/compound/addAutoMirrored.py create mode 100755 tools/compound/import_tokens.sh diff --git a/tools/compound/addAutoMirrored.py b/tools/compound/addAutoMirrored.py new file mode 100644 index 0000000000..3d20211bc6 --- /dev/null +++ b/tools/compound/addAutoMirrored.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 + +files = [ + "ic_compound_arrow_left.xml", + "ic_compound_arrow_right.xml", + "ic_compound_arrow_up_right.xml", + "ic_compound_attachment.xml", + "ic_compound_block.xml", + "ic_compound_chart.xml", + "ic_compound_chat.xml", + "ic_compound_chat_new.xml", + "ic_compound_chat_problem.xml", + "ic_compound_chat_solid.xml", + "ic_compound_chevron_left.xml", + "ic_compound_chevron_right.xml", + "ic_compound_cloud.xml", + "ic_compound_cloud_solid.xml", + "ic_compound_collapse.xml", + "ic_compound_company.xml", + "ic_compound_compose.xml", + "ic_compound_copy.xml", + "ic_compound_dark_mode.xml", + "ic_compound_devices.xml", + "ic_compound_document.xml", + "ic_compound_earpiece.xml", + "ic_compound_edit.xml", + "ic_compound_edit_solid.xml", + "ic_compound_expand.xml", + "ic_compound_extensions.xml", + "ic_compound_extensions_solid.xml", + "ic_compound_file_error.xml", + "ic_compound_files.xml", + "ic_compound_forward.xml", + "ic_compound_guest.xml", + "ic_compound_history.xml", + "ic_compound_host.xml", + "ic_compound_image.xml", + "ic_compound_image_error.xml", + "ic_compound_indent_decrease.xml", + "ic_compound_indent_increase.xml", + "ic_compound_italic.xml", + "ic_compound_key.xml", + "ic_compound_key_off.xml", + "ic_compound_key_off_solid.xml", + "ic_compound_key_solid.xml", + "ic_compound_leave.xml", + "ic_compound_link.xml", + "ic_compound_list_bulleted.xml", + "ic_compound_lock_off.xml", + "ic_compound_mark_as_unread.xml", + "ic_compound_mark_threads_as_read.xml", + "ic_compound_marker_read_receipts.xml", + "ic_compound_mic_off.xml", + "ic_compound_mic_off_solid.xml", + "ic_compound_notifications_off.xml", + "ic_compound_notifications_off_solid.xml", + "ic_compound_offline.xml", + "ic_compound_play.xml", + "ic_compound_play_solid.xml", + "ic_compound_polls.xml", + "ic_compound_polls_end.xml", + "ic_compound_pop_out.xml", + "ic_compound_qr_code.xml", + "ic_compound_quote.xml", + "ic_compound_reaction_add.xml", + "ic_compound_reply.xml", + "ic_compound_restart.xml", + "ic_compound_room.xml", + "ic_compound_search.xml", + "ic_compound_send.xml", + "ic_compound_send_solid.xml", + "ic_compound_share_android.xml", + "ic_compound_sidebar.xml", + "ic_compound_sign_out.xml", + "ic_compound_spinner.xml", + "ic_compound_spotlight.xml", + "ic_compound_switch_camera_solid.xml", + "ic_compound_threads.xml", + "ic_compound_threads_solid.xml", + "ic_compound_unknown.xml", + "ic_compound_unknown_solid.xml", + "ic_compound_unpin.xml", + "ic_compound_user_add.xml", + "ic_compound_user_add_solid.xml", + "ic_compound_video_call.xml", + "ic_compound_video_call_declined_solid.xml", + "ic_compound_video_call_missed_solid.xml", + "ic_compound_video_call_off.xml", + "ic_compound_video_call_off_solid.xml", + "ic_compound_video_call_solid.xml", + "ic_compound_visibility_off.xml", + "ic_compound_voice_call.xml", + "ic_compound_voice_call_solid.xml", + "ic_compound_volume_off.xml", + "ic_compound_volume_off_solid.xml", + "ic_compound_volume_on.xml", + "ic_compound_volume_on_solid.xml", +] + + +def main(): + for file in files: + # Open file for read + with open("./compound/src/main/res/drawable/" + file, 'r') as f: + data = f.read().split("\n") + # Open file to write + with open("./compound/src/main/res/drawable/" + file, 'w') as f: + # Write new data + # write the 3 first lines in data + for i in range(3): + f.write(data[i] + "\n") + f.write(" android:autoMirrored=\"true\"\n") + # write the rest of the data + for i in range(3, len(data) - 1): + f.write(data[i] + "\n") + print("Added autoMirrored to " + str(len(files)) + " files.") + + +if __name__ == "__main__": + main() diff --git a/tools/compound/import_tokens.sh b/tools/compound/import_tokens.sh new file mode 100755 index 0000000000..adcd8d23af --- /dev/null +++ b/tools/compound/import_tokens.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -e + +SHORT=b,: +LONG=branch,: +BRANCH='main' + +while getopts b: flag +do + case "${flag}" in + b) BRANCH=${OPTARG};; + esac +done + +echo "Branch used: $BRANCH" + +echo "Cloning the compound-design-tokens repository..." +if [ -d tmp ]; then + echo "Deleting tmp folder..." + rm -rf tmp +fi +mkdir tmp +pushd tmp +git clone --branch $BRANCH https://github.com/vector-im/compound-design-tokens + +echo "Copying files from tokens repository..." +cp -R compound-design-tokens/assets/android/res/drawable ../compound/src/main/res/ +cp -R compound-design-tokens/assets/android/src/* ../compound/src/main/kotlin/io/element/android/compound/tokens/generated/ +popd + +echo "Adding autoMirrored attribute..." +python3 ./scripts/addAutoMirrored.py + +echo "Removing temporary files..." +rm -rf tmp + +echo "Done!" From a0046e1e1a2d8a17bc074a43ab1b4ca6c235eab8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Oct 2025 20:43:57 +0000 Subject: [PATCH 38/73] fix(deps): update telephoto to v0.18.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d9990bbbf9..a7aac36173 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,7 +44,7 @@ showkase = "1.0.5" appyx = "1.7.1" sqldelight = "2.1.0" wysiwyg = "2.39.0" -telephoto = "0.17.0" +telephoto = "0.18.0" haze = "1.6.10" # Dependency analysis From baa5eb0b729d163b3558697006d6b1268e4f6929 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:32:55 +0200 Subject: [PATCH 39/73] Update compound scripts. Ensure drawable folder is emptied before importing tokens and import again. --- tools/compound/addAutoMirrored.py | 4 ++-- tools/compound/import_tokens.sh | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tools/compound/addAutoMirrored.py b/tools/compound/addAutoMirrored.py index 3d20211bc6..a8e22c42a5 100644 --- a/tools/compound/addAutoMirrored.py +++ b/tools/compound/addAutoMirrored.py @@ -101,10 +101,10 @@ files = [ def main(): for file in files: # Open file for read - with open("./compound/src/main/res/drawable/" + file, 'r') as f: + with open("./libraries/compound/src/main/res/drawable/" + file, 'r') as f: data = f.read().split("\n") # Open file to write - with open("./compound/src/main/res/drawable/" + file, 'w') as f: + with open("./libraries/compound/src/main/res/drawable/" + file, 'w') as f: # Write new data # write the 3 first lines in data for i in range(3): diff --git a/tools/compound/import_tokens.sh b/tools/compound/import_tokens.sh index adcd8d23af..700decf81e 100755 --- a/tools/compound/import_tokens.sh +++ b/tools/compound/import_tokens.sh @@ -2,37 +2,38 @@ set -e -SHORT=b,: -LONG=branch,: BRANCH='main' while getopts b: flag do case "${flag}" in b) BRANCH=${OPTARG};; + *) echo "usage: $0 [-b branch]" >&2 + exit 1 ;; esac done echo "Branch used: $BRANCH" echo "Cloning the compound-design-tokens repository..." -if [ -d tmp ]; then - echo "Deleting tmp folder..." - rm -rf tmp +if [ -d tmpCompound ]; then + echo "Deleting tmpCompound folder..." + rm -rf tmpCompound fi -mkdir tmp -pushd tmp -git clone --branch $BRANCH https://github.com/vector-im/compound-design-tokens +mkdir tmpCompound +pushd tmpCompound +git clone --branch "${BRANCH}" https://github.com/vector-im/compound-design-tokens echo "Copying files from tokens repository..." -cp -R compound-design-tokens/assets/android/res/drawable ../compound/src/main/res/ -cp -R compound-design-tokens/assets/android/src/* ../compound/src/main/kotlin/io/element/android/compound/tokens/generated/ +rm -R ../libraries/compound/src/main/res/drawable +cp -R compound-design-tokens/assets/android/res/drawable ../libraries/compound/src/main/res/ +cp -R compound-design-tokens/assets/android/src/* ../libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/ popd echo "Adding autoMirrored attribute..." -python3 ./scripts/addAutoMirrored.py +python3 ./tools/compound/addAutoMirrored.py echo "Removing temporary files..." -rm -rf tmp +rm -rf tmpCompound echo "Done!" From 20e8765a3a5eff8b0e5ad2203dbd9bc6b7a5b234 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:39:54 +0200 Subject: [PATCH 40/73] We do not need to use support library --- libraries/compound/build.gradle.kts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/compound/build.gradle.kts b/libraries/compound/build.gradle.kts index fd99035c65..9ec6ce0e58 100644 --- a/libraries/compound/build.gradle.kts +++ b/libraries/compound/build.gradle.kts @@ -12,13 +12,6 @@ plugins { android { namespace = "io.element.android.compound" - defaultConfig { - vectorDrawables { - useSupportLibrary = true - generatedDensities() - } - } - dependencies { implementation(libs.showkase) } From b41fb4144e8c797cd6fb63afcc85ca668a529485 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:50:43 +0200 Subject: [PATCH 41/73] Fix some quality issue --- .../android/compound/annotations/CoreColorToken.kt | 5 ++++- .../android/compound/previews/CompoundIconsPreview.kt | 8 +++++--- .../io/element/android/compound/previews/Typography.kt | 2 +- .../io/element/android/compound/theme/AvatarColors.kt | 10 ++++++---- .../io/element/android/compound/theme/ElementTheme.kt | 5 +++-- .../android/compound/theme/MaterialTextPreview.kt | 1 - .../kotlin/io/element/android/compound/theme/Theme.kt | 2 +- 7 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt index b80b8653ea..a56ecb38a8 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/annotations/CoreColorToken.kt @@ -7,7 +7,10 @@ package io.element.android.compound.annotations -@RequiresOptIn("This is a Core color token, which should only be used to declare semantic colors, otherwise it would look the same on both light and dark modes. Only use it as is if you know what you are doing.") +@RequiresOptIn( + message = "This is a Core color token, which should only be used to declare semantic colors, otherwise it" + + " would look the same on both light and dark modes. Only use it as is if you know what you are doing." +) @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) annotation class CoreColorToken diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt index 6e7b8ea825..0ee0546ca4 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/CompoundIconsPreview.kt @@ -38,6 +38,8 @@ import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList @Preview(widthDp = 730, heightDp = 1800) @Composable @@ -90,14 +92,14 @@ private fun IconsCompoundPreview( } IconsPreview( title = title, - content = content.toList(), + content = content.toImmutableList(), ) } @Composable internal fun IconsPreview( title: String, - content: List<@Composable ColumnScope.() -> Unit>, + content: ImmutableList<@Composable ColumnScope.() -> Unit>, ) = Surface { Column( modifier = Modifier @@ -138,4 +140,4 @@ internal fun IconsPreview( } } } -} \ No newline at end of file +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt index 2fc93aeef0..5d5f31f203 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt @@ -19,7 +19,7 @@ import io.element.android.compound.theme.ElementTheme @Preview @Composable -fun TypographyPreview() = ElementTheme { +internal fun TypographyPreview() = ElementTheme { Surface { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { with(ElementTheme.materialTypography) { diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt index 9b2ea07376..506e1c8063 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/AvatarColors.kt @@ -20,6 +20,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList /** * Data class to hold avatar colors. @@ -53,7 +55,7 @@ internal fun AvatarColorsPreviewLight() { val chunks = avatarColors().chunked(4) Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { for (chunk in chunks) { - AvatarColorRow(chunk) + AvatarColorRow(chunk.toImmutableList()) } } } @@ -66,14 +68,14 @@ internal fun AvatarColorsPreviewDark() { val chunks = avatarColors().chunked(4) Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { for (chunk in chunks) { - AvatarColorRow(chunk) + AvatarColorRow(chunk.toImmutableList()) } } } } @Composable -private fun AvatarColorRow(colors: List) { +private fun AvatarColorRow(colors: ImmutableList) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { colors.forEach { color -> Box( @@ -88,4 +90,4 @@ private fun AvatarColorRow(colors: List) { } } } -} \ No newline at end of file +} diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt index 63994f24e9..08c30cf917 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt @@ -77,7 +77,7 @@ object ElementTheme { get() = LocalCompoundColors.current.isLight } -/* Global variables (application level) */ +// Global variables (application level) internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLight } /** @@ -100,7 +100,8 @@ fun ElementTheme( darkTheme: Boolean = isSystemInDarkTheme(), applySystemBarsUpdate: Boolean = true, lightStatusBar: Boolean = !darkTheme, - dynamicColor: Boolean = false, /* true to enable MaterialYou */ + // true to enable MaterialYou + dynamicColor: Boolean = false, compoundLight: SemanticColors = compoundColorsLight, compoundDark: SemanticColors = compoundColorsDark, materialColorsLight: ColorScheme = compoundLight.toMaterialColorScheme(), diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt index 12f4cd18f8..724d440161 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/MaterialTextPreview.kt @@ -119,7 +119,6 @@ private fun MaterialPreview( } } - @Composable private fun TextPreview( name: String, diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt index 03ca5c598f..c6e9b47eb7 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/Theme.kt @@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.map enum class Theme { System, Dark, - Light; + Light, } val themes = listOf(Theme.System, Theme.Dark, Theme.Light) From 04d0666ca0f5f616a76d63583e771ff87902068e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 18:55:47 +0200 Subject: [PATCH 42/73] Exclude generated files from being analyzed --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.editorconfig b/.editorconfig index ac30459c21..2ab3cbeae7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -913,3 +913,8 @@ ij_yaml_sequence_on_new_line = false ij_yaml_space_before_colon = false ij_yaml_spaces_within_braces = true ij_yaml_spaces_within_brackets = true + +[**/generated/**] +generated_code = true +ij_formatter_enabled = false +ktlint = disabled \ No newline at end of file From 97efdfd0172a4874baa32e8df1ac04ea5848e9e0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 19:12:51 +0200 Subject: [PATCH 43/73] Add exception for Konsist test. --- .../android/tests/konsist/KonsistComposableTest.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistComposableTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistComposableTest.kt index d1435e409d..181c63350b 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistComposableTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistComposableTest.kt @@ -36,6 +36,15 @@ class KonsistComposableTest { "OutlinedButton", "SimpleAlertDialogContent", "TextButton", + "AvatarColorsPreviewLight", + "AvatarColorsPreviewDark", + "IconsCompoundPreviewLight", + "IconsCompoundPreviewRtl", + "IconsCompoundPreviewDark", + "CompoundSemanticColorsLight", + "CompoundSemanticColorsLightHc", + "CompoundSemanticColorsDark", + "CompoundSemanticColorsDarkHc", ) .assertTrue( additionalMessage = From 2d1a3ac929e27454813a36e23de434cb452dca24 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 19:38:32 +0200 Subject: [PATCH 44/73] Update ref in enterprise module. --- enterprise | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enterprise b/enterprise index 95789d4011..ffc02b8d0f 160000 --- a/enterprise +++ b/enterprise @@ -1 +1 @@ -Subproject commit 95789d40119499eba8a79284df9dd2306405b099 +Subproject commit ffc02b8d0f35188c3ef8a876dc1532bfe3e533da From 9938b746698c95ff107d41b68c0a733307e582aa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Oct 2025 20:27:17 +0200 Subject: [PATCH 45/73] Fix lint issue --- .../kotlin/io/element/android/compound/theme/ElementTheme.kt | 3 ++- .../element/android/compound/theme/ForcedDarkElementTheme.kt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt index 08c30cf917..7535de0acd 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt @@ -10,6 +10,7 @@ package io.element.android.compound.theme import android.os.Build import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle +import androidx.activity.compose.LocalActivity import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.ColorScheme @@ -135,7 +136,7 @@ fun ElementTheme( } if (applySystemBarsUpdate) { - val activity = LocalContext.current as? ComponentActivity + val activity = LocalActivity.current as? ComponentActivity LaunchedEffect(statusBarColorScheme, darkTheme, lightStatusBar) { activity?.enableEdgeToEdge( // For Status bar use the background color of the app diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt index fce1a920d0..cd168713ae 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ForcedDarkElementTheme.kt @@ -9,13 +9,13 @@ package io.element.android.compound.theme import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle +import androidx.activity.compose.LocalActivity import androidx.activity.enableEdgeToEdge import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext /** * Can be used to force a composable in dark theme. @@ -28,7 +28,7 @@ fun ForcedDarkElementTheme( ) { val colorScheme = MaterialTheme.colorScheme val wasDarkTheme = !ElementTheme.colors.isLight - val activity = LocalContext.current as? ComponentActivity + val activity = LocalActivity.current as? ComponentActivity DisposableEffect(Unit) { onDispose { activity?.enableEdgeToEdge( From d4e295807fee194e668b0ed13c155fb650663a8f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 10:16:29 +0200 Subject: [PATCH 46/73] Import Compound tests from project https://github.com/element-hq/compound-android --- .gitattributes | 1 + .../workflows/scripts/recordScreenshots.sh | 3 + .github/workflows/tests.yml | 1 + build.gradle.kts | 9 +- gradle.properties | 4 + gradle/libs.versions.toml | 7 ++ libraries/compound/build.gradle.kts | 11 +++ .../screenshots/Avatar Colors - Dark.png | 3 + .../screenshots/Avatar Colors - Light.png | 3 + .../screenshots/Compound Icons - Dark.png | 3 + .../screenshots/Compound Icons - Light.png | 3 + .../screenshots/Compound Icons - Rtl.png | 3 + .../Compound Semantic Colors - Dark HC.png | 3 + .../Compound Semantic Colors - Dark.png | 3 + .../Compound Semantic Colors - Light HC.png | 3 + .../Compound Semantic Colors - Light.png | 3 + .../screenshots/Compound Typography.png | 3 + .../Compound Vector Icons - Dark.png | 3 + .../Compound Vector Icons - Light.png | 3 + .../screenshots/ForcedDarkElementTheme.png | 3 + .../compound/screenshots/Legacy Colors.png | 3 + .../screenshots/Material Typography.png | 3 + .../Material3 Colors - Dark HC.png | 3 + .../screenshots/Material3 Colors - Dark.png | 3 + .../Material3 Colors - Light HC.png | 3 + .../screenshots/Material3 Colors - Light.png | 3 + .../screenshots/MaterialText Colors.png | 3 + .../screenshots/MaterialYou Theme - Dark.png | 3 + .../screenshots/MaterialYou Theme - Light.png | 3 + .../compound/screenshot/AvatarColorsTest.kt | 33 +++++++ .../compound/screenshot/CompoundIconTest.kt | 66 +++++++++++++ .../screenshot/CompoundTypographyTest.kt | 65 +++++++++++++ .../screenshot/ForcedDarkElementThemeTest.kt | 57 +++++++++++ .../compound/screenshot/LegacyColorsTest.kt | 72 ++++++++++++++ .../screenshot/MaterialColorSchemeTest.kt | 96 +++++++++++++++++++ .../compound/screenshot/MaterialTextTest.kt | 29 ++++++ .../screenshot/MaterialTypographyTest.kt | 29 ++++++ .../screenshot/MaterialYouThemeTest.kt | 68 +++++++++++++ .../compound/screenshot/SemanticColorsTest.kt | 44 +++++++++ .../screenshot/utils/ScreenshotUtils.kt | 18 ++++ 40 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 libraries/compound/screenshots/Avatar Colors - Dark.png create mode 100644 libraries/compound/screenshots/Avatar Colors - Light.png create mode 100644 libraries/compound/screenshots/Compound Icons - Dark.png create mode 100644 libraries/compound/screenshots/Compound Icons - Light.png create mode 100644 libraries/compound/screenshots/Compound Icons - Rtl.png create mode 100644 libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png create mode 100644 libraries/compound/screenshots/Compound Semantic Colors - Dark.png create mode 100644 libraries/compound/screenshots/Compound Semantic Colors - Light HC.png create mode 100644 libraries/compound/screenshots/Compound Semantic Colors - Light.png create mode 100644 libraries/compound/screenshots/Compound Typography.png create mode 100644 libraries/compound/screenshots/Compound Vector Icons - Dark.png create mode 100644 libraries/compound/screenshots/Compound Vector Icons - Light.png create mode 100644 libraries/compound/screenshots/ForcedDarkElementTheme.png create mode 100644 libraries/compound/screenshots/Legacy Colors.png create mode 100644 libraries/compound/screenshots/Material Typography.png create mode 100644 libraries/compound/screenshots/Material3 Colors - Dark HC.png create mode 100644 libraries/compound/screenshots/Material3 Colors - Dark.png create mode 100644 libraries/compound/screenshots/Material3 Colors - Light HC.png create mode 100644 libraries/compound/screenshots/Material3 Colors - Light.png create mode 100644 libraries/compound/screenshots/MaterialText Colors.png create mode 100644 libraries/compound/screenshots/MaterialYou Theme - Dark.png create mode 100644 libraries/compound/screenshots/MaterialYou Theme - Light.png create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/AvatarColorsTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundIconTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/ForcedDarkElementThemeTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/LegacyColorsTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialColorSchemeTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTextTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTypographyTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialYouThemeTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/SemanticColorsTest.kt create mode 100644 libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/utils/ScreenshotUtils.kt diff --git a/.gitattributes b/.gitattributes index 5f13ff4efb..0a1fc8653d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ screenshots/**/*.png filter=lfs diff=lfs merge=lfs -text +libraries/compound/screenshots/** filter=lfs diff=lfs merge=lfs -text **/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text **/docs/images-lfs/*.png filter=lfs diff=lfs merge=lfs -text libraries/mediaupload/impl/src/test/assets/* filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/scripts/recordScreenshots.sh b/.github/workflows/scripts/recordScreenshots.sh index a610c6cc69..963a3c908b 100755 --- a/.github/workflows/scripts/recordScreenshots.sh +++ b/.github/workflows/scripts/recordScreenshots.sh @@ -56,6 +56,9 @@ echo "Deleting previous screenshots" echo "Record screenshots" ./gradlew recordPaparazziDebug --stacktrace $GRADLE_ARGS +echo "Record screenshots (Compound)" +./gradlew :libraries:compound:recordRoborazziDebug --stacktrace -PpreDexEnable=false --max-workers 4 --warn $GRADLE_ARGS + echo "Committing changes" git config http.sslVerify false diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c0249642f4..22c302cbb3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -78,6 +78,7 @@ jobs: name: tests-and-screenshot-tests-results path: | **/build/paparazzi/failures/ + **/build/roborazzi/failures/ **/build/reports/tests/*UnitTest/ # https://github.com/codecov/codecov-action diff --git a/build.gradle.kts b/build.gradle.kts index 7171d5b079..484d43a929 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,7 @@ plugins { alias(libs.plugins.compose.compiler) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.dependencycheck) apply false + alias(libs.plugins.roborazzi) apply false alias(libs.plugins.dependencyanalysis) alias(libs.plugins.detekt) alias(libs.plugins.ktlint) @@ -180,16 +181,22 @@ tasks.register("runQualityChecks") { // Make sure to delete old screenshots before recording new ones subprojects { val snapshotsDir = File("${project.projectDir}/src/test/snapshots") + val snapshotsDir2 = File("${project.projectDir}/screenshots") val removeOldScreenshotsTask = tasks.register("removeOldSnapshots") { - onlyIf { snapshotsDir.exists() } + onlyIf { snapshotsDir.exists() || snapshotsDir2.exists() } doFirst { println("Delete previous screenshots located at $snapshotsDir\n") snapshotsDir.deleteRecursively() + println("Delete previous screenshots located at $snapshotsDir2\n") + snapshotsDir2.deleteRecursively() } } tasks.findByName("recordPaparazzi")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordPaparazziDebug")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordPaparazziRelease")?.dependsOn(removeOldScreenshotsTask) + tasks.findByName("recordRoborazzi")?.dependsOn(removeOldScreenshotsTask) + tasks.findByName("recordRoborazziDebug")?.dependsOn(removeOldScreenshotsTask) + tasks.findByName("recordRoborazziRelease")?.dependsOn(removeOldScreenshotsTask) } subprojects { diff --git a/gradle.properties b/gradle.properties index 18399ccf06..a2c7228ed2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -54,3 +54,7 @@ ksp.allow.all.target.configuration=false # Used to prevent detekt from reusing invalid cached rules detekt.use.worker.api=true + +# Let test include roborazzi verification +# https://github.com/takahirom/roborazzi?tab=readme-ov-file#roborazzitest +roborazzi.test.verify=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 78b085fd41..f837a1e55b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" +roborazzi = "1.46.1" # Jetbrain datetime = "0.7.1" @@ -226,6 +227,11 @@ google_autoservice_annotations = { module = "com.google.auto.service:auto-servic # Miscellaneous androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } +# Test +test_roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref = "roborazzi" } +test_roborazzi_compose = { module = "io.github.takahirom.roborazzi:roborazzi-compose", version.ref = "roborazzi" } +test_roborazzi_junit = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi" } + [bundles] [plugins] @@ -243,6 +249,7 @@ dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12" dependencycheck = "org.owasp.dependencycheck:12.1.6" dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" } paparazzi = "app.cash.paparazzi:2.0.0-alpha02" +roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } diff --git a/libraries/compound/build.gradle.kts b/libraries/compound/build.gradle.kts index 9ec6ce0e58..cbdb09d451 100644 --- a/libraries/compound/build.gradle.kts +++ b/libraries/compound/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.testCommonDependencies + /* * Copyright 2022, 2025 New Vector Ltd. * @@ -7,12 +9,21 @@ plugins { id("io.element.android-compose-library") + alias(libs.plugins.roborazzi) } android { namespace = "io.element.android.compound" + testOptions { + unitTests.isIncludeAndroidResources = true + } + dependencies { implementation(libs.showkase) + testCommonDependencies(libs) + testImplementation(libs.test.roborazzi) + testImplementation(libs.test.roborazzi.compose) + testImplementation(libs.test.roborazzi.junit) } } diff --git a/libraries/compound/screenshots/Avatar Colors - Dark.png b/libraries/compound/screenshots/Avatar Colors - Dark.png new file mode 100644 index 0000000000..5cf6cbda89 --- /dev/null +++ b/libraries/compound/screenshots/Avatar Colors - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:caf2de32caf0fa5368da899297e2eabd5a0c6891dd94f81295ef8a933d79ce16 +size 10751 diff --git a/libraries/compound/screenshots/Avatar Colors - Light.png b/libraries/compound/screenshots/Avatar Colors - Light.png new file mode 100644 index 0000000000..7069762082 --- /dev/null +++ b/libraries/compound/screenshots/Avatar Colors - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80e44e94d7b23af2ec4fd1c5a871851ae2567b40e478b30145de199076f20e95 +size 11296 diff --git a/libraries/compound/screenshots/Compound Icons - Dark.png b/libraries/compound/screenshots/Compound Icons - Dark.png new file mode 100644 index 0000000000..acac494f89 --- /dev/null +++ b/libraries/compound/screenshots/Compound Icons - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bc48b9f792da838f9fc2c2a630cbbbb906de851a138cc1ac8b7bf67b801ad84 +size 211300 diff --git a/libraries/compound/screenshots/Compound Icons - Light.png b/libraries/compound/screenshots/Compound Icons - Light.png new file mode 100644 index 0000000000..c6b76c46bb --- /dev/null +++ b/libraries/compound/screenshots/Compound Icons - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85fd2c67ff42829b8580ab5c0c2af1fee40973f5c0b34ef7de00e3663cee8e4 +size 223041 diff --git a/libraries/compound/screenshots/Compound Icons - Rtl.png b/libraries/compound/screenshots/Compound Icons - Rtl.png new file mode 100644 index 0000000000..ce2ffe2e88 --- /dev/null +++ b/libraries/compound/screenshots/Compound Icons - Rtl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:406b62991171a146e891f95bcad0321ebc60cf1fe2cabc9caedbb17fb062af13 +size 224320 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png new file mode 100644 index 0000000000..4890b91886 --- /dev/null +++ b/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:578e9b5a38791e2686a7b9ba5c461eb1d1fb29dfbe950bf46c113ad75ceac175 +size 327758 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark.png new file mode 100644 index 0000000000..4cc125b4c8 --- /dev/null +++ b/libraries/compound/screenshots/Compound Semantic Colors - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cab40fc0506c8f2a2efafb1199e85f1da3ebacb49b176e9105e3f95175f85ee +size 325565 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png new file mode 100644 index 0000000000..5a8f5a6b32 --- /dev/null +++ b/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:174f9d4ee70a29c0c8c2a01a15daeb14281530678ff7d7fb19a208bfd789533a +size 309210 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light.png b/libraries/compound/screenshots/Compound Semantic Colors - Light.png new file mode 100644 index 0000000000..f010626dda --- /dev/null +++ b/libraries/compound/screenshots/Compound Semantic Colors - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7598b98462c015f2bf74b3ea3ad95fc0220b2efb9bb81ac56025cf6a158e3f8a +size 308976 diff --git a/libraries/compound/screenshots/Compound Typography.png b/libraries/compound/screenshots/Compound Typography.png new file mode 100644 index 0000000000..095ad6c71d --- /dev/null +++ b/libraries/compound/screenshots/Compound Typography.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac84a7175c4a4897aa28eddcf722b7997c6576f612eb38fa09ffabcf7be11e00 +size 119496 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Dark.png b/libraries/compound/screenshots/Compound Vector Icons - Dark.png new file mode 100644 index 0000000000..2b535c348b --- /dev/null +++ b/libraries/compound/screenshots/Compound Vector Icons - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ff6dfdfab51332cad3bdfa351a4d0e305de5f899853575a8514858cc871e904 +size 83609 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Light.png b/libraries/compound/screenshots/Compound Vector Icons - Light.png new file mode 100644 index 0000000000..bc29dcd24d --- /dev/null +++ b/libraries/compound/screenshots/Compound Vector Icons - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca38f5f23c282a6dc4c01a54705f71bf8c927aeac9c1df0a1f3abe50c10b1b85 +size 89336 diff --git a/libraries/compound/screenshots/ForcedDarkElementTheme.png b/libraries/compound/screenshots/ForcedDarkElementTheme.png new file mode 100644 index 0000000000..d7182aa47c --- /dev/null +++ b/libraries/compound/screenshots/ForcedDarkElementTheme.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03bdb2f3de01d40b8f85ba87b395cdab2e5225aded2f40a0892077798bca6066 +size 22328 diff --git a/libraries/compound/screenshots/Legacy Colors.png b/libraries/compound/screenshots/Legacy Colors.png new file mode 100644 index 0000000000..2ecdda2ed7 --- /dev/null +++ b/libraries/compound/screenshots/Legacy Colors.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e9d676a1ef20a7228e985f62d346265ff9c31d1860a219540f012c063c9345e +size 33652 diff --git a/libraries/compound/screenshots/Material Typography.png b/libraries/compound/screenshots/Material Typography.png new file mode 100644 index 0000000000..6c22c364b9 --- /dev/null +++ b/libraries/compound/screenshots/Material Typography.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d27f813acc9e8dc3960f5205809c8c0d2ba0fa51fd9e3ca07964b866b125e87d +size 110171 diff --git a/libraries/compound/screenshots/Material3 Colors - Dark HC.png b/libraries/compound/screenshots/Material3 Colors - Dark HC.png new file mode 100644 index 0000000000..4cc7609c89 --- /dev/null +++ b/libraries/compound/screenshots/Material3 Colors - Dark HC.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85969829577e158bdd1d0f21c8b3a2334dcde79cb50d5e2331d06d5423332be2 +size 160754 diff --git a/libraries/compound/screenshots/Material3 Colors - Dark.png b/libraries/compound/screenshots/Material3 Colors - Dark.png new file mode 100644 index 0000000000..3738cf6a79 --- /dev/null +++ b/libraries/compound/screenshots/Material3 Colors - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca64da1dc373dc49503ee525ae3331e73d0ab12053993a1ef19dcab1e67b08c4 +size 159123 diff --git a/libraries/compound/screenshots/Material3 Colors - Light HC.png b/libraries/compound/screenshots/Material3 Colors - Light HC.png new file mode 100644 index 0000000000..8d64857d13 --- /dev/null +++ b/libraries/compound/screenshots/Material3 Colors - Light HC.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01622bca20a132ec5a874fc1a2d0ffd45e7ce6d7849c4d607d79c7bc51d6c6a9 +size 163322 diff --git a/libraries/compound/screenshots/Material3 Colors - Light.png b/libraries/compound/screenshots/Material3 Colors - Light.png new file mode 100644 index 0000000000..a1d5d1f2ce --- /dev/null +++ b/libraries/compound/screenshots/Material3 Colors - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87c0c4ff42d17137d554708ce33f40f214ec608eca4ca87af0b2adab63de6bb7 +size 162891 diff --git a/libraries/compound/screenshots/MaterialText Colors.png b/libraries/compound/screenshots/MaterialText Colors.png new file mode 100644 index 0000000000..f8f77ccca2 --- /dev/null +++ b/libraries/compound/screenshots/MaterialText Colors.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4be10c3bb9900d27a3b406eca0cb902b0ff9cdf90e8e3cf1ae7760aa7c5d47d9 +size 377446 diff --git a/libraries/compound/screenshots/MaterialYou Theme - Dark.png b/libraries/compound/screenshots/MaterialYou Theme - Dark.png new file mode 100644 index 0000000000..8c5bc9d1ef --- /dev/null +++ b/libraries/compound/screenshots/MaterialYou Theme - Dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c166e5371bb1922a9c016438a3cdfd0d68197237969d53a04f92baf6d53c4ac0 +size 164925 diff --git a/libraries/compound/screenshots/MaterialYou Theme - Light.png b/libraries/compound/screenshots/MaterialYou Theme - Light.png new file mode 100644 index 0000000000..70cccac69b --- /dev/null +++ b/libraries/compound/screenshots/MaterialYou Theme - Light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d936948cbad69d6935f2d2738d33682a55f044dfb1af8b5c9b8323c5f4318971 +size 163558 diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/AvatarColorsTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/AvatarColorsTest.kt new file mode 100644 index 0000000000..015cd5341c --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/AvatarColorsTest.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.AvatarColorsPreviewDark +import io.element.android.compound.theme.AvatarColorsPreviewLight +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class AvatarColorsTest { + @Test + @Config(sdk = [35], qualifiers = "xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("Avatar Colors - Light.png")) { + AvatarColorsPreviewLight() + } + captureRoboImage(file = screenshotFile("Avatar Colors - Dark.png")) { + AvatarColorsPreviewDark() + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundIconTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundIconTest.kt new file mode 100644 index 0000000000..9ae73a6205 --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundIconTest.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.IconsCompoundPreviewDark +import io.element.android.compound.previews.IconsCompoundPreviewLight +import io.element.android.compound.previews.IconsCompoundPreviewRtl +import io.element.android.compound.previews.IconsPreview +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import kotlinx.collections.immutable.toImmutableList +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class CompoundIconTest { + @Test + @Config(sdk = [35], qualifiers = "w1024dp-h2048dp") + fun screenshots() { + captureRoboImage(file = screenshotFile("Compound Icons - Light.png")) { + IconsCompoundPreviewLight() + } + captureRoboImage(file = screenshotFile("Compound Icons - Rtl.png")) { + IconsCompoundPreviewRtl() + } + captureRoboImage(file = screenshotFile("Compound Icons - Dark.png")) { + IconsCompoundPreviewDark() + } + captureRoboImage(file = screenshotFile("Compound Vector Icons - Light.png")) { + val content: List<@Composable ColumnScope.() -> Unit> = CompoundIcons.all.map { + @Composable { Icon(imageVector = it, contentDescription = null) } + } + ElementTheme { + IconsPreview( + title = "Compound Vector Icons", + content = content.toImmutableList() + ) + } + } + captureRoboImage(file = screenshotFile("Compound Vector Icons - Dark.png")) { + val content: List<@Composable ColumnScope.() -> Unit> = CompoundIcons.all.map { + @Composable { Icon(imageVector = it, contentDescription = null) } + } + ElementTheme(darkTheme = true) { + IconsPreview( + title = "Compound Vector Icons", + content = content.toImmutableList() + ) + } + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt new file mode 100644 index 0000000000..2d50e6287d --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.TypographyTokens +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class CompoundTypographyTest { + @Test + @Config(sdk = [35], qualifiers = "h2048dp-xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("Compound Typography.png")) { + ElementTheme { + Surface { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + with(TypographyTokens) { + TypographyTokenPreview(fontHeadingXlBold, "Heading XL Bold") + TypographyTokenPreview(fontHeadingXlRegular, "Heading XL Regular") + TypographyTokenPreview(fontHeadingLgBold, "Heading LG Bold") + TypographyTokenPreview(fontHeadingLgRegular, "Heading LG Regular") + TypographyTokenPreview(fontHeadingMdBold, "Heading MD Bold") + TypographyTokenPreview(fontHeadingMdRegular, "Heading MD Regular") + TypographyTokenPreview(fontHeadingSmMedium, "Heading SM Medium") + TypographyTokenPreview(fontHeadingSmRegular, "Heading SM Regular") + TypographyTokenPreview(fontBodyLgMedium, "Body LG Medium") + TypographyTokenPreview(fontBodyLgRegular, "Body LG Regular") + TypographyTokenPreview(fontBodyMdMedium, "Body MD Medium") + TypographyTokenPreview(fontBodyMdRegular, "Body MD Regular") + TypographyTokenPreview(fontBodySmMedium, "Body SM Medium") + TypographyTokenPreview(fontBodySmRegular, "Body SM Regular") + TypographyTokenPreview(fontBodyXsMedium, "Body XS Medium") + TypographyTokenPreview(fontBodyXsRegular, "Body XS Regular") + } + } + } + } + } + } + + @Composable + private fun TypographyTokenPreview(style: TextStyle, text: String) { + Text(text = text, style = style) + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/ForcedDarkElementThemeTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/ForcedDarkElementThemeTest.kt new file mode 100644 index 0000000000..341b7cb650 --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/ForcedDarkElementThemeTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.theme.ForcedDarkElementTheme +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class ForcedDarkElementThemeTest { + @Test + @Config(sdk = [35], qualifiers = "xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("ForcedDarkElementTheme.png")) { + ElementTheme { + Surface { + Column( + modifier = Modifier.padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text(text = "Outside") + ForcedDarkElementTheme { + Surface { + Box(modifier = Modifier.fillMaxSize()) { + Text(text = "Inside ForcedDarkElementTheme", modifier = Modifier.align(Alignment.Center)) + } + } + } + } + } + } + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/LegacyColorsTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/LegacyColorsTest.kt new file mode 100644 index 0000000000..ecfbbe81cd --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/LegacyColorsTest.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.ColorPreview +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.theme.LinkColor +import io.element.android.compound.theme.SnackBarLabelColorDark +import io.element.android.compound.theme.SnackBarLabelColorLight +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class LegacyColorsTest { + @Test + @Config(sdk = [35], qualifiers = "xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("Legacy Colors.png")) { + ElementTheme { + Surface { + Column(modifier = Modifier.padding(16.dp)) { + Text(text = "Legacy Colors") + Spacer(modifier = Modifier.height(10.dp)) + LegacyColorPreview( + color = LinkColor, + name = "Link" + ) + LegacyColorPreview( + color = SnackBarLabelColorLight, + name = "SnackBar Label - Light" + ) + LegacyColorPreview( + color = SnackBarLabelColorDark, + name = "SnackBar Label - Dark" + ) + } + } + } + } + } + + @Composable + private fun LegacyColorPreview(color: Color, name: String) { + ColorPreview( + backgroundColor = Color.White, + foregroundColor = Color.Black, + name = name, + color = color + ) + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialColorSchemeTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialColorSchemeTest.kt new file mode 100644 index 0000000000..7542eaa4fc --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialColorSchemeTest.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ColorsSchemeDarkHcPreview +import io.element.android.compound.theme.ColorsSchemeDarkPreview +import io.element.android.compound.theme.ColorsSchemeLightHcPreview +import io.element.android.compound.theme.ColorsSchemeLightPreview +import io.element.android.compound.theme.ElementTheme +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class MaterialColorSchemeTest { + @Test + @Config(sdk = [35], qualifiers = "h2048dp-xhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("Material3 Colors - Light.png")) { + ElementTheme { + Surface { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "M3 Light colors", + style = TextStyle.Default.copy(fontSize = 18.sp), + ) + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemeLightPreview() + } + } + } + } + captureRoboImage(file = screenshotFile("Material3 Colors - Light HC.png")) { + ElementTheme { + Surface { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "M3 Light HC colors", + style = TextStyle.Default.copy(fontSize = 18.sp), + ) + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemeLightHcPreview() + } + } + } + } + captureRoboImage(file = screenshotFile("Material3 Colors - Dark.png")) { + ElementTheme { + Surface { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "M3 Dark colors", + style = TextStyle.Default.copy(fontSize = 18.sp), + ) + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemeDarkPreview() + } + } + } + } + captureRoboImage(file = screenshotFile("Material3 Colors - Dark HC.png")) { + ElementTheme { + Surface { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "M3 Dark HC colors", + style = TextStyle.Default.copy(fontSize = 18.sp), + ) + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemeDarkHcPreview() + } + } + } + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTextTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTextTest.kt new file mode 100644 index 0000000000..764d4de77c --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTextTest.kt @@ -0,0 +1,29 @@ +/* + * 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.compound.screenshot + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.MaterialTextPreview +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class MaterialTextTest { + @Test + @Config(sdk = [35], qualifiers = "w480dp-h1200dp-xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("MaterialText Colors.png")) { + MaterialTextPreview() + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTypographyTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTypographyTest.kt new file mode 100644 index 0000000000..4f77a070ed --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialTypographyTest.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.TypographyPreview +import io.element.android.compound.screenshot.utils.screenshotFile +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class MaterialTypographyTest { + @Test + @Config(sdk = [35], qualifiers = "h2048dp-xxhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("Material Typography.png")) { + TypographyPreview() + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialYouThemeTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialYouThemeTest.kt new file mode 100644 index 0000000000..694d2c9fc6 --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/MaterialYouThemeTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.ColorsSchemePreview +import io.element.android.compound.screenshot.utils.screenshotFile +import io.element.android.compound.theme.ElementTheme +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class MaterialYouThemeTest { + @Test + @Config(sdk = [35], qualifiers = "h2048dp-xhdpi") + fun screenshots() { + captureRoboImage(file = screenshotFile("MaterialYou Theme - Light.png")) { + ElementTheme(dynamicColor = true) { + Surface { + Column( + modifier = Modifier.padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text(text = "Material You Theme - Light") + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemePreview(Color.White, Color.Black, ElementTheme.materialColors) + } + } + } + } + captureRoboImage(file = screenshotFile("MaterialYou Theme - Dark.png")) { + ElementTheme(dynamicColor = true, darkTheme = true) { + Surface { + Column( + modifier = Modifier.padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text(text = "Material You Theme - Dark") + Spacer(modifier = Modifier.height(12.dp)) + ColorsSchemePreview(Color.White, Color.Black, ElementTheme.materialColors) + } + } + } + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/SemanticColorsTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/SemanticColorsTest.kt new file mode 100644 index 0000000000..7e5fabd96a --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/SemanticColorsTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2023, 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.compound.screenshot + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.CompoundSemanticColorsDark +import io.element.android.compound.previews.CompoundSemanticColorsDarkHc +import io.element.android.compound.previews.CompoundSemanticColorsLight +import io.element.android.compound.previews.CompoundSemanticColorsLightHc +import io.element.android.compound.screenshot.utils.screenshotFile +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class SemanticColorsTest { + @Config(sdk = [35], qualifiers = "h2000dp-xhdpi") + @Test + fun screenshots() { + captureRoboImage(file = screenshotFile("Compound Semantic Colors - Light.png")) { + CompoundSemanticColorsLight() + } + + captureRoboImage(file = screenshotFile("Compound Semantic Colors - Light HC.png")) { + CompoundSemanticColorsLightHc() + } + + captureRoboImage(file = screenshotFile("Compound Semantic Colors - Dark.png")) { + CompoundSemanticColorsDark() + } + + captureRoboImage(file = screenshotFile("Compound Semantic Colors - Dark HC.png")) { + CompoundSemanticColorsDarkHc() + } + } +} diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/utils/ScreenshotUtils.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/utils/ScreenshotUtils.kt new file mode 100644 index 0000000000..3d4c9b3824 --- /dev/null +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/utils/ScreenshotUtils.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2023, 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.compound.screenshot.utils + +import java.io.File + +/** + * Returns a [File] object for a screenshot with the given [filename]. + * This is to ensure we have a consistent location for all screenshots. + */ +fun screenshotFile(filename: String): File { + return File("screenshots", filename) +} From 11d6e7e2892b8793a5e739a3749651b3516b004e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 11:00:30 +0200 Subject: [PATCH 47/73] Fix CI on screeshot recording --- .github/workflows/scripts/recordScreenshots.sh | 3 +++ build.gradle.kts | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scripts/recordScreenshots.sh b/.github/workflows/scripts/recordScreenshots.sh index 963a3c908b..19469e69e3 100755 --- a/.github/workflows/scripts/recordScreenshots.sh +++ b/.github/workflows/scripts/recordScreenshots.sh @@ -56,6 +56,9 @@ echo "Deleting previous screenshots" echo "Record screenshots" ./gradlew recordPaparazziDebug --stacktrace $GRADLE_ARGS +echo "Deleting previous screenshots" +./gradlew removeOldScreenshots --stacktrace --warn $GRADLE_ARGS + echo "Record screenshots (Compound)" ./gradlew :libraries:compound:recordRoborazziDebug --stacktrace -PpreDexEnable=false --max-workers 4 --warn $GRADLE_ARGS diff --git a/build.gradle.kts b/build.gradle.kts index 484d43a929..b7662aeb56 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -181,19 +181,28 @@ tasks.register("runQualityChecks") { // Make sure to delete old screenshots before recording new ones subprojects { val snapshotsDir = File("${project.projectDir}/src/test/snapshots") - val snapshotsDir2 = File("${project.projectDir}/screenshots") val removeOldScreenshotsTask = tasks.register("removeOldSnapshots") { - onlyIf { snapshotsDir.exists() || snapshotsDir2.exists() } + onlyIf { snapshotsDir.exists() } doFirst { println("Delete previous screenshots located at $snapshotsDir\n") snapshotsDir.deleteRecursively() - println("Delete previous screenshots located at $snapshotsDir2\n") - snapshotsDir2.deleteRecursively() } } tasks.findByName("recordPaparazzi")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordPaparazziDebug")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordPaparazziRelease")?.dependsOn(removeOldScreenshotsTask) +} + +// Make sure to delete old snapshot before recording new ones +subprojects { + val screenshotsDir = File("${project.projectDir}/screenshots") + val removeOldScreenshotsTask = tasks.register("removeOldScreenshots") { + onlyIf { screenshotsDir.exists() } + doFirst { + println("Delete previous screenshots located at $screenshotsDir\n") + screenshotsDir.deleteRecursively() + } + } tasks.findByName("recordRoborazzi")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordRoborazziDebug")?.dependsOn(removeOldScreenshotsTask) tasks.findByName("recordRoborazziRelease")?.dependsOn(removeOldScreenshotsTask) From 1e67a01f0487697ed7576fb897bccf9456b35235 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 11:06:08 +0200 Subject: [PATCH 48/73] Enable Spaces by default. --- .../element/android/libraries/featureflag/api/FeatureFlags.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 96c452a790..a7c4113b62 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -71,8 +71,7 @@ enum class FeatureFlags( Space( key = "feature.space", title = "Spaces", - description = "Spaces are under active development, only developers should enable this flag for now.", - defaultValue = { false }, + defaultValue = { true }, isFinished = false, ), PrintLogsToLogcat( From 7095b460b3953781c723ebf125b64ca56cdb6147 Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Mon, 6 Oct 2025 12:38:51 +0200 Subject: [PATCH 49/73] Sync Strings from Localazy (#5460) Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com> --- .../src/main/res/values-fr/translations.xml | 11 + .../src/main/res/values-ru/translations.xml | 11 + .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-ru/translations.xml | 2 + .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-ro/translations.xml | 1 + .../src/main/res/values-ru/translations.xml | 2 + .../src/main/res/values-ru/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 4 + .../src/main/res/values-ro/translations.xml | 2 + .../src/main/res/values-ru/translations.xml | 8 + .../src/main/res/values-nb/translations.xml | 7 + .../src/main/res/values-ru/translations.xml | 4 + .../impl/src/main/res/values/localazy.xml | 1 + .../src/main/res/values-ro/translations.xml | 2 + .../src/main/res/values-ru/translations.xml | 2 + .../src/main/res/values-nb/translations.xml | 3 + .../src/main/res/values-ro/translations.xml | 2 + .../src/main/res/values-ru/translations.xml | 2 + .../src/main/res/values-cs/translations.xml | 1 + .../src/main/res/values-da/translations.xml | 1 + .../src/main/res/values-de/translations.xml | 1 + .../src/main/res/values-et/translations.xml | 2 + .../src/main/res/values-fr/translations.xml | 4 + .../src/main/res/values-hu/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 5 + .../src/main/res/values-ro/translations.xml | 14 + .../src/main/res/values-ru/translations.xml | 14 + .../src/main/res/values-et/translations.xml | 5 +- .../src/main/res/values-nb/translations.xml | 6 +- .../src/main/res/values-ro/translations.xml | 5 +- .../src/main/res/values-ru/translations.xml | 7 +- .../src/main/res/values-et/translations.xml | 3 + .../src/main/res/values-fr/translations.xml | 3 + .../src/main/res/values-nb/translations.xml | 3 + .../src/main/res/values-ro/translations.xml | 12 + .../src/main/res/values-ru/translations.xml | 12 + .../impl/src/main/res/values/localazy.xml | 3 + .../main/res/values-en-rUS/translations.xml | 1 + .../src/main/res/values-et/translations.xml | 1 + .../src/main/res/values-fr/translations.xml | 2 + .../src/main/res/values-nb/translations.xml | 30 + .../src/main/res/values-ro/translations.xml | 18 +- .../src/main/res/values-ru/translations.xml | 42 +- .../src/main/res/values/localazy.xml | 9 + ....spaces_SpaceAnnouncementView_Day_0_de.png | 3 + ...pl.components_RoomSummaryRow_Day_32_de.png | 4 +- ...pl.components_RoomSummaryRow_Day_33_de.png | 4 +- ...pl.components_RoomSummaryRow_Day_34_de.png | 4 +- ...pl.components_RoomSummaryRow_Day_35_de.png | 3 + ...me.impl.spaces_HomeSpacesView_Day_0_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_0_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_1_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_2_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_3_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_4_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_5_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_6_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_7_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_8_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_9_de.png | 3 + ...res.space.impl.root_SpaceView_Day_2_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_3_de.png | 4 +- ...ncoming.ui_SessionDetailsView_Day_0_de.png | 4 +- ...ming_IncomingVerificationView_Day_0_de.png | 4 +- ...ming_IncomingVerificationView_Day_1_de.png | 4 +- ...ming_IncomingVerificationView_Day_2_de.png | 4 +- ...ming_IncomingVerificationView_Day_4_de.png | 4 +- ...ing_OutgoingVerificationView_Day_10_de.png | 4 +- ....components_SpaceRoomItemView_Day_0_de.png | 3 + ....components_SpaceRoomItemView_Day_1_de.png | 3 + ....components_SpaceRoomItemView_Day_2_de.png | 3 + ....components_SpaceRoomItemView_Day_3_de.png | 3 + ....components_SpaceRoomItemView_Day_4_de.png | 3 + ....components_SpaceRoomItemView_Day_5_de.png | 3 + ....components_SpaceRoomItemView_Day_6_de.png | 3 + ....components_SpaceRoomItemView_Day_7_de.png | 3 + screenshots/html/data.js | 1796 +++++++++-------- 79 files changed, 1241 insertions(+), 945 deletions(-) create mode 100644 features/announcement/impl/src/main/res/values-fr/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-ru/translations.xml create mode 100644 features/space/impl/src/main/res/values-nb/translations.xml create mode 100644 features/space/impl/src/main/res/values-ro/translations.xml create mode 100644 features/space/impl/src/main/res/values-ru/translations.xml create mode 100644 screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png create mode 100644 screenshots/de/features.home.impl.components_RoomSummaryRow_Day_35_de.png create mode 100644 screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_0_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_1_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_de.png create mode 100644 screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_de.png diff --git a/features/announcement/impl/src/main/res/values-fr/translations.xml b/features/announcement/impl/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..a529e99100 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-fr/translations.xml @@ -0,0 +1,11 @@ + + + "Voir les espaces que vous avez créés ou rejoints" + "Accepter ou refuser les invitations aux espaces" + "Découvrez les salons que vous pouvez joindre depuis vos espaces" + "Rejoindre les espaces publics" + "Quittez les espaces dont vous êtes membre." + "La création et la gestion des espaces seront bientôt disponibles." + "Bienvenue dans la version bêta des espaces! Avec cette première version, vous pourrez :" + "Ajout des espaces" + diff --git a/features/announcement/impl/src/main/res/values-ru/translations.xml b/features/announcement/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..8b930b2ca0 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,11 @@ + + + "Просмотр пространств, которые вы создали или к которым присоединились" + "Принимать или отклонять приглашения в пространства" + "Откройте для себя все комнаты, к которым вы можете присоединиться в своих пространствах." + "Присоединиться к публичному пространству" + "Покинуть все пространства, к которым вы присоединились" + "Создание и управление пространствами станет доступно в ближайшее время." + "Добро пожаловать в бета-версию Spaces! В этой первой версии вы сможете:" + "Знакомство с пространствами" + diff --git a/features/changeroommemberroles/impl/src/main/res/values-nb/translations.xml b/features/changeroommemberroles/impl/src/main/res/values-nb/translations.xml index 33c9fabe24..2e3379b98a 100644 --- a/features/changeroommemberroles/impl/src/main/res/values-nb/translations.xml +++ b/features/changeroommemberroles/impl/src/main/res/values-nb/translations.xml @@ -17,6 +17,7 @@ "Rediger administratorer" "Du vil ikke kunne angre denne handlingen. Du forfremmer brukeren til å ha samme rettighetsnivå som deg." "Legg til administrator?" + "Du kan ikke angre denne handlingen. Du overfører eierskapet til de valgte brukerne. Når du forlater siden, vil dette være permanent." "Overføre eierskapet?" "Degradere" "Du vil ikke kunne angre denne endringen ettersom du degraderer deg selv, og hvis du er den siste privilegerte brukeren i rommet, vil det være umulig å få tilbake privilegiene." diff --git a/features/home/impl/src/main/res/values-nb/translations.xml b/features/home/impl/src/main/res/values-nb/translations.xml index 198bb7112d..172ca33485 100644 --- a/features/home/impl/src/main/res/values-nb/translations.xml +++ b/features/home/impl/src/main/res/values-nb/translations.xml @@ -33,6 +33,7 @@ Inntil videre kan du velge bort filtre for å se de andre chattene dine""Invitasjoner" "Du har ingen ventende invitasjoner." "Lav prioritet" + "Du har ingen lavprioriterte chatter ennå" "Du kan velge bort filtre for å se de andre chattene dine" "Du har ikke chatter for dette utvalget" "Personer" diff --git a/features/home/impl/src/main/res/values-ru/translations.xml b/features/home/impl/src/main/res/values-ru/translations.xml index 5ff6a3c714..975e48a160 100644 --- a/features/home/impl/src/main/res/values-ru/translations.xml +++ b/features/home/impl/src/main/res/values-ru/translations.xml @@ -13,6 +13,7 @@ "Чтобы больше не пропускать важные звонки, разрешите приложению показывать полноэкранные уведомления на заблокированном экране телефона." "Улучшите качество звонков" "Все чаты" + "Пространства" "Вы уверены, что хотите отклонить приглашение в %1$s?" "Отклонить приглашение" "Вы уверены, что хотите отказаться от личного общения с %1$s?" @@ -32,6 +33,7 @@ "Приглашения" "У вас нет отложенных приглашений." "Низкий приоритет" + "У вас пока нет чатов с низким приоритетом." "Вы можете убрать фильтры, чтобы увидеть другие ваши чаты." "У вас нет чатов для этой подборки" "Пользователи" diff --git a/features/joinroom/impl/src/main/res/values-nb/translations.xml b/features/joinroom/impl/src/main/res/values-nb/translations.xml index a349def982..f494bfa4f8 100644 --- a/features/joinroom/impl/src/main/res/values-nb/translations.xml +++ b/features/joinroom/impl/src/main/res/values-nb/translations.xml @@ -15,6 +15,7 @@ "Dette rommet er enten kun for inviterte, eller det kan være begrensninger for tilgang på områdenivå." "Glem dette rommet" "Du trenger en invitasjon for å bli med i dette rommet" + "Invitert av" "Bli med i rommet" "Du må kanskje bli invitert eller være medlem av et område for å bli med." "Send forespørsel om å bli med" diff --git a/features/joinroom/impl/src/main/res/values-ro/translations.xml b/features/joinroom/impl/src/main/res/values-ro/translations.xml index ca7764aa62..2246013403 100644 --- a/features/joinroom/impl/src/main/res/values-ro/translations.xml +++ b/features/joinroom/impl/src/main/res/values-ro/translations.xml @@ -15,6 +15,7 @@ "Această cameră este fie accesibilă numai pe bază de invitație, fie exista restricții de acces la nivel de spațiu." "Uitați această cameră" "Aveți nevoie de o invitație pentru a vă alătura acestei camere." + "Invitat de" "Alăturați-vă camerei" "Este posibil să fie necesar să fiți invitat sau să fiți membru al unui spațiu pentru a vă alătura." "Trimiteți o cerere de alăturare" diff --git a/features/joinroom/impl/src/main/res/values-ru/translations.xml b/features/joinroom/impl/src/main/res/values-ru/translations.xml index 4c87355000..bfb00f72a6 100644 --- a/features/joinroom/impl/src/main/res/values-ru/translations.xml +++ b/features/joinroom/impl/src/main/res/values-ru/translations.xml @@ -15,9 +15,11 @@ "Доступ в эту комнату возможен только по приглашениям или может быть ограничен на уровне пространства." "Забыть эту комнату" "Вам необходимо приглашение для того, чтобы присоединиться к этой комнате" + "Приглашен" "Присоединиться к комнате" "Чтобы присоединиться, вам необходимо приглашение или быть участником сообщества." "Отправить запрос на присоединение" + "Разрешенные символы %1$d %2$d" "Сообщение (опционально)" "Вы получите приглашение присоединиться к комнате, как только ваш запрос будет принят." "Запрос на присоединение отправлен" diff --git a/features/login/impl/src/main/res/values-ru/translations.xml b/features/login/impl/src/main/res/values-ru/translations.xml index f362537644..8ce58135aa 100644 --- a/features/login/impl/src/main/res/values-ru/translations.xml +++ b/features/login/impl/src/main/res/values-ru/translations.xml @@ -13,6 +13,7 @@ "Другое" "Используйте другого поставщика учетных записей, например, собственный частный сервер или рабочую учетную запись." "Сменить поставщика учетной записи" + "Google Play" "Требуется приложение Element Pro для %1$s. Пожалуйста, загрузите его из магазина." "Требуется Element Pro" "Нам не удалось связаться с этим домашним сервером. Убедитесь, что вы правильно ввели URL-адрес домашнего сервера. Если URL-адрес указан правильно, обратитесь к администратору домашнего сервера за дополнительной помощью." diff --git a/features/messages/impl/src/main/res/values-nb/translations.xml b/features/messages/impl/src/main/res/values-nb/translations.xml index deee637c09..5df3e5eac3 100644 --- a/features/messages/impl/src/main/res/values-nb/translations.xml +++ b/features/messages/impl/src/main/res/values-nb/translations.xml @@ -7,13 +7,17 @@ "Gjenstander" "Smilefjes og mennesker" "Reising og steder" + "Nylige emojier" "Symboler" "Teksting er kanskje ikke synlig for personer som bruker eldre apper." + "Trykk for å endre kvaliteten på videoopplastingen" "Filen kunne ikke lastes opp." "Kunne ikke behandle medier for opplasting, vennligst prøv igjen." "Opplasting av medier mislyktes, vennligst prøv igjen." "Maksimal tillatt filstørrelse er %1$s." "Filen er for stor til å lastes opp" + "Optimaliser bildekvaliteten" + "Behandler…" "Blokker bruker" "Kryss av for om du vil skjule alle nåværende og fremtidige meldinger fra denne brukeren" "Denne meldingen vil bli rapportert til hjemmeserverens administratorer. De vil ikke kunne lese noen krypterte meldinger." diff --git a/features/messages/impl/src/main/res/values-ro/translations.xml b/features/messages/impl/src/main/res/values-ro/translations.xml index da8344f18a..a121bc7843 100644 --- a/features/messages/impl/src/main/res/values-ro/translations.xml +++ b/features/messages/impl/src/main/res/values-ro/translations.xml @@ -7,6 +7,7 @@ "Obiecte" "Fețe zâmbitoare & Oameni" "Călătorii & Locuri" + "Emoticoane recente" "Simboluri" "Este posibil ca descrierile să nu fie vizibile pentru persoanele care folosesc aplicații mai vechi." "Atingeți pentru a modifica calitatea încărcării videoclipului" @@ -15,6 +16,7 @@ "Încărcarea fișierelor media a eșuat, încercați din nou." "Dimensiunea maximă permisă pentru fișiere este de %1$s." "Fișierul este prea mare pentru a fi încărcat." + "Elementul %1$d din %2$d" "Optimizați calitatea imaginii" "Se procesează…" "Blocați utilizatorul" diff --git a/features/messages/impl/src/main/res/values-ru/translations.xml b/features/messages/impl/src/main/res/values-ru/translations.xml index 0cc79fba16..4656a5978b 100644 --- a/features/messages/impl/src/main/res/values-ru/translations.xml +++ b/features/messages/impl/src/main/res/values-ru/translations.xml @@ -7,10 +7,18 @@ "Объекты" "Улыбки и люди" "Путешествия и места" + "Недавние эмодзи" "Символы" "Подпись может быть не видна пользователям старых приложений." + "Нажмите, чтобы изменить качество загружаемого видео." + "Файл не может быть загружен." "Не удалось обработать медиафайл для загрузки, попробуйте еще раз." "Не удалось загрузить медиафайлы, попробуйте еще раз." + "Максимальный размер файла: %1$s." + "Файл слишком большой для загрузки." + "Элемент %1$d из %2$d" + "Оптимизировать качество изображения" + "Обработка…" "Заблокировать пользователя" "Отметьте, хотите ли вы скрыть все текущие и будущие сообщения от этого пользователя" "Это сообщение будет передано администратору вашего домашнего сервера. Они не смогут прочитать зашифрованные сообщения." diff --git a/features/preferences/impl/src/main/res/values-nb/translations.xml b/features/preferences/impl/src/main/res/values-nb/translations.xml index 84283b898b..f30bbc9e90 100644 --- a/features/preferences/impl/src/main/res/values-nb/translations.xml +++ b/features/preferences/impl/src/main/res/values-nb/translations.xml @@ -13,6 +13,13 @@ "Last opp bilder og videoer raskere og reduser databruken" "Optimaliser mediekvaliteten" "Moderasjon og sikkerhet" + "Optimaliser bilder automatisk for raskere opplastinger og mindre filstørrelser." + "Optimaliser kvaliteten på bildeopplasting" + "%1$s. Trykk her for å endre." + "Høy (1080p)" + "Lav (480p)" + "Standard (720p)" + "Kvalitet på videoopplasting" "Leverandør av pushvarsling" "Deaktiver rik tekstredigering for å skrive Markdown manuelt." "Lesebekreftelser" diff --git a/features/preferences/impl/src/main/res/values-ru/translations.xml b/features/preferences/impl/src/main/res/values-ru/translations.xml index 59d19b0210..72a9f75c7c 100644 --- a/features/preferences/impl/src/main/res/values-ru/translations.xml +++ b/features/preferences/impl/src/main/res/values-ru/translations.xml @@ -10,9 +10,13 @@ "Адрес указан неверно, удостоверьтесь, что вы указали протокол (http/https) и правильный адрес." "Скрыть аватары в запросах на приглашение в комнату" "Скрыть предварительный просмотр медиафайлов на временной шкале" + "Лаборатория" "Загружайте фотографии и видео быстрее и сокращайте потребление трафика" "Оптимизировать качество мультимедиа" "Модерация и безопасность" + "Автоматически оптимизируйте изображения для более быстрой загрузки и уменьшения размера файлов." + "Оптимизируйте качество загрузки изображения" + "%1$s. Нажмите здесь, чтобы изменить." "Высокое (1080p)" "Низкое (480p)" "Среднее (720p)" diff --git a/features/preferences/impl/src/main/res/values/localazy.xml b/features/preferences/impl/src/main/res/values/localazy.xml index 8b3c9d1d82..89c5ffba85 100644 --- a/features/preferences/impl/src/main/res/values/localazy.xml +++ b/features/preferences/impl/src/main/res/values/localazy.xml @@ -10,6 +10,7 @@ "Invalid URL, please make sure you include the protocol (http/https) and the correct address." "Hide avatars in room invite requests" "Hide media previews in timeline" + "Labs" "Upload photos and videos faster and reduce data usage" "Optimise media quality" "Moderation and Safety" diff --git a/features/rageshake/impl/src/main/res/values-ro/translations.xml b/features/rageshake/impl/src/main/res/values-ro/translations.xml index 6c2a7cb611..f342ffd4c5 100644 --- a/features/rageshake/impl/src/main/res/values-ro/translations.xml +++ b/features/rageshake/impl/src/main/res/values-ro/translations.xml @@ -14,5 +14,7 @@ "Trimiteți captură de ecran" "Pentru a verifica că lucrurile funcționează conform așteptărilor, log-uri vor fi trimise împreună cu mesajul. Acestea vor fi private. Pentru a trimite doar mesajul, dezactivați această setare." "%1$s s-a blocat ultima dată când a fost folosit. Doriți să ne trimiteți un raport?" + "Dacă întâmpinați probleme cu notificările, încărcarea setărilor notificărilor ne poate ajuta să identificăm cauza principală." + "Trimiteți setările notificărilor" "Vizualizați log-urile" diff --git a/features/rageshake/impl/src/main/res/values-ru/translations.xml b/features/rageshake/impl/src/main/res/values-ru/translations.xml index 5a8f2ceb71..f1d5216405 100644 --- a/features/rageshake/impl/src/main/res/values-ru/translations.xml +++ b/features/rageshake/impl/src/main/res/values-ru/translations.xml @@ -14,5 +14,7 @@ "Отправить снимок экрана" "Чтобы убедиться, что все работает правильно, в сообщение будут включены журналы. Чтобы отправить сообщение без журналов, отключите эту настройку." "При последнем использовании %1$s произошел сбой. Хотите поделиться отчетом о сбое?" + "Если у вас возникли проблемы с уведомлениями, загрузка настроек уведомлений может помочь нам определить основную причину." + "Настройки отправки уведомлений" "Просмотр журналов" diff --git a/features/roomdetails/impl/src/main/res/values-nb/translations.xml b/features/roomdetails/impl/src/main/res/values-nb/translations.xml index 596b387b04..16042fdf57 100644 --- a/features/roomdetails/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nb/translations.xml @@ -22,6 +22,7 @@ "Rediger administratorer" "Du vil ikke kunne angre denne handlingen. Du forfremmer brukeren til å ha samme rettighetsnivå som deg." "Legg til administrator?" + "Du kan ikke angre denne handlingen. Du overfører eierskapet til de valgte brukerne. Når du forlater siden, vil dette være permanent." "Overføre eierskapet?" "Degradere" "Du vil ikke kunne angre denne endringen ettersom du degraderer deg selv, og hvis du er den siste privilegerte brukeren i rommet, vil det være umulig å få tilbake privilegiene." @@ -49,6 +50,8 @@ "Det oppstod en feil ved lasting av varslingsinnstillinger." "Mislyktes i å dempe dette rommet, prøv igjen." "Mislyktes i å oppheve dempingen av dette rommet, prøv igjen." + "Ikke lukk appen før den er ferdig." + "Forbereder invitasjoner…" "Inviter folk" "Forlat samtalen" "Forlat rommet" diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index fbdf3132a4..7379a45550 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -50,6 +50,8 @@ "A apărut o eroare la încărcarea setărilor pentru notificari." "Dezactivarea notificarilor pentru această cameră a eșuat, încercați din nou." "Activarea notificarilor pentru această cameră a eșuat, încercați din nou." + "Nu închideți aplicația până nu se termină." + "Se pregătesc invitațiile…" "Invitați prieteni" "Părăsiți conversația" "Părăsiți camera" diff --git a/features/roomdetails/impl/src/main/res/values-ru/translations.xml b/features/roomdetails/impl/src/main/res/values-ru/translations.xml index e24adbd6c1..82efd71adf 100644 --- a/features/roomdetails/impl/src/main/res/values-ru/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ru/translations.xml @@ -50,6 +50,8 @@ "Произошла ошибка при загрузке настроек уведомлений." "Не удалось отключить звук в этой комнате, попробуйте еще раз." "Не удалось включить звук в эту комнату, попробуйте еще раз." + "Не закрывайте приложение, пока не закончите." + "Подготовка приглашений…" "Пригласить в комнату" "Покинуть беседу" "Покинуть комнату" diff --git a/features/space/impl/src/main/res/values-cs/translations.xml b/features/space/impl/src/main/res/values-cs/translations.xml index 8ab1f64989..0c645f0650 100644 --- a/features/space/impl/src/main/res/values-cs/translations.xml +++ b/features/space/impl/src/main/res/values-cs/translations.xml @@ -1,5 +1,6 @@ + "%1$s (Správce)" "Opustit %1$d místnost a prostor" "Opustit %1$d místnosti a prostor" diff --git a/features/space/impl/src/main/res/values-da/translations.xml b/features/space/impl/src/main/res/values-da/translations.xml index 4863ff7cca..ec7da700a9 100644 --- a/features/space/impl/src/main/res/values-da/translations.xml +++ b/features/space/impl/src/main/res/values-da/translations.xml @@ -1,5 +1,6 @@ + "%1$s (Admin)" "Forlad %1$d rum og klynge" "Forlad %1$d rum og klynger" diff --git a/features/space/impl/src/main/res/values-de/translations.xml b/features/space/impl/src/main/res/values-de/translations.xml index 2ecdac3115..d42e979ef1 100644 --- a/features/space/impl/src/main/res/values-de/translations.xml +++ b/features/space/impl/src/main/res/values-de/translations.xml @@ -1,5 +1,6 @@ + "%1$s (Admin)" "%1$d Chat und Space verlassen" "%1$d Chats und Space verlassen" diff --git a/features/space/impl/src/main/res/values-et/translations.xml b/features/space/impl/src/main/res/values-et/translations.xml index d60171dc89..3ab5d65284 100644 --- a/features/space/impl/src/main/res/values-et/translations.xml +++ b/features/space/impl/src/main/res/values-et/translations.xml @@ -1,9 +1,11 @@ + "%1$s (Peakasutaja)" "Lahku %1$d-st jututoast ja kogukonnast" "Lahku %1$d-st jututoast ja kogukonnast" "Sellega eemaldad end ka kõikidest antud kogukonna jututubadest." + "Sind ei saa järgnevatest jututubadest eemaldada, kuna oled seal/neis ainus peakasutaja:" "Kas lahkud %1$s kogukonnast?" diff --git a/features/space/impl/src/main/res/values-fr/translations.xml b/features/space/impl/src/main/res/values-fr/translations.xml index 3c9f2d3ab9..cf37795848 100644 --- a/features/space/impl/src/main/res/values-fr/translations.xml +++ b/features/space/impl/src/main/res/values-fr/translations.xml @@ -1,9 +1,13 @@ + "%1$s (Admin)" "Quitter %1$d salon et l’espace" "Quitter %1$d salons et l’espace" "Sélectionnez les salons que vous souhaitez quitter et dont vous n’êtes pas le seul administrateur:" + "Vous devez désigner un autre administrateur pour cet espace avant de pouvoir partir." + "Vous ne quitterez pas le ou les salons suivants car vous y êtes le seul administrateur:" "Quitter %1$s?" + "Vous êtes le seul administrateur de %1$s" diff --git a/features/space/impl/src/main/res/values-hu/translations.xml b/features/space/impl/src/main/res/values-hu/translations.xml index bb326f759a..79a8733df2 100644 --- a/features/space/impl/src/main/res/values-hu/translations.xml +++ b/features/space/impl/src/main/res/values-hu/translations.xml @@ -1,5 +1,6 @@ + "%1$s (Adminisztrátor)" "%1$d szoba és tér elhagyása" "%1$d szoba és tér elhagyása" diff --git a/features/space/impl/src/main/res/values-nb/translations.xml b/features/space/impl/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..e25a2ba6f0 --- /dev/null +++ b/features/space/impl/src/main/res/values-nb/translations.xml @@ -0,0 +1,5 @@ + + + "Velg rommene du vil forlate, som du ikke er den eneste administratoren for:" + "Forlat %1$s?" + diff --git a/features/space/impl/src/main/res/values-ro/translations.xml b/features/space/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..6ff2a5dfa8 --- /dev/null +++ b/features/space/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,14 @@ + + + "%1$s (Admin)" + + "Părăsiți %1$d cameră și spațiul" + "Părăsiți %1$d camere și spațiul" + "Părăsiți %1$d camere și spațiul" + + "Selectați camerele pe care doriți să le părăsiți și în care nu sunteți singurul administrator:" + "Trebuie să desemnați un alt administrator pentru acest spațiu înainte de a-l părăsi." + "Nu veți părăsi următoarele camere deoarece sunteți singurul administrator:" + "Părăsiți %1$s?" + "Sunteți singurul administrator pentru %1$s" + diff --git a/features/space/impl/src/main/res/values-ru/translations.xml b/features/space/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..0df1b9224a --- /dev/null +++ b/features/space/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,14 @@ + + + "%1$s (Администратор)" + + "Покинуть %1$d комнату и пространство" + "Покинуть %1$d комнат и пространство" + "Покинуть %1$d комнат и пространство" + + "Выберите комнаты, которые вы хотите покинуть и в которых вы не являетесь единственным администратором:" + "Прежде чем покинуть это пространство, вам необходимо назначить другого администратора." + "Вы не будете удалены из следующих комнат, поскольку вы являетесь единственным администратором:" + "Выйти из %1$s?" + "Вы единственный администратор для %1$s" + diff --git a/features/verifysession/impl/src/main/res/values-et/translations.xml b/features/verifysession/impl/src/main/res/values-et/translations.xml index fa2a5733da..2c43794b72 100644 --- a/features/verifysession/impl/src/main/res/values-et/translations.xml +++ b/features/verifysession/impl/src/main/res/values-et/translations.xml @@ -16,8 +16,9 @@ "Palun kinnita, et allpool näidatud emojid vastavad täpselt neile, mida kuvatakse teise kasutaja seadmes." "Kinnita, et kõik järgnevalt kuvatud numbrid on täpselt samad, mida sa näed oma teises sessioonis." "Võrdle numbreid" - "Sinu uus sessioon on nüüd verifitseeritud. Sellel sessioonil on nüüd ligipääs sinu krüptitud sõnumitele ja teised osapooled näevad teda usaldusväärsena." + "Võid nüüd sõnumeid oma teises seadmes turvaliselt saata ja vastu võtta." "Nüüd sa võid sõnumite vastuvõtmisel ja saatmisel selle kasutaja identiteeti usaldada." + "Seade on verifitseeritud" "Sisesta taastevõti" "Kas verifitseerimine aegus, teine osapool keeldus vastamast või tekkis vastuste mittevastavus." "Saamaks ligipääsu krüptitud sõnumite ajaloole tõesta et tegemist on sinuga." @@ -44,7 +45,7 @@ "Lisaturvalisuse nimel soovib teine kasutaja sinu identiteeti verifitseerida. Järgmiseks näed sa emojisid, mida peate omavahel võrdlema." "Sa peaksid teises seadmes nägema hüpikakent. Palun alusta sealt verifitseerimist." "Alusta verifitseerimist teises seadmes" - "Ootame teise seadme järgi" + "Alusta verifitseerimist teises seadmes" "Ootame teise kasutaja järgi" "Kui oled nõustunud, siis saad sa verifitseerimist jätkata." "Jätkamaks nõustu verifitseerimisprotsessi alustamisega oma teises sessioonis." diff --git a/features/verifysession/impl/src/main/res/values-nb/translations.xml b/features/verifysession/impl/src/main/res/values-nb/translations.xml index afb8298a20..2696ae62f4 100644 --- a/features/verifysession/impl/src/main/res/values-nb/translations.xml +++ b/features/verifysession/impl/src/main/res/values-nb/translations.xml @@ -11,12 +11,12 @@ "Bruk en annen enhet" "Venter på en annen enhet…" "Noe virker ikke riktig. Enten ble forespørselen tidsavbrutt eller forespørselen ble avslått." - "Bekreft at emojiene nedenfor samsvarer med de som vises på den andre sesjonen din." + "Bekreft at emojiene nedenfor samsvarer med de som vises på den andre enheten din." "Sammenlign emojier" "Bekreft at emojiene nedenfor stemmer overens med de som vises på den andre brukerens enhet." "Kontroller at tallene nedenfor stemmer overens med dem som vises på den andre sesjonen." "Sammenlign tallene" - "Den nye sesjonen din er nå bekreftet. Den har tilgang til de krypterte meldingene dine, og andre brukere vil se den som klarert." + "Nå kan du lese eller sende meldinger sikkert på den andre enheten din." "Nå kan du stole på identiteten til denne brukeren når du sender eller mottar meldinger." "Skriv inn gjenopprettingsnøkkel" "Enten ble forespørselen tidsavbrutt, forespørselen ble avslått eller det var en feil i verifiseringen." @@ -44,7 +44,7 @@ "For ekstra sikkerhet vil en annen bruker bekrefte identiteten din. Du får se et sett med emojier som du må sammenligne." "Du skal se en popup på den andre enheten. Start bekreftelsen derfra nå." "Start verifiseringen på den andre enheten" - "Venter på den andre enheten" + "Start verifiseringen på den andre enheten" "Venter på den andre brukeren" "Når du er akseptert, kan du fortsette med verifiseringen." "Godta forespørselen om å starte bekreftelsesprosessen i den andre sesjonen for å fortsette." diff --git a/features/verifysession/impl/src/main/res/values-ro/translations.xml b/features/verifysession/impl/src/main/res/values-ro/translations.xml index 08064b056a..065649526f 100644 --- a/features/verifysession/impl/src/main/res/values-ro/translations.xml +++ b/features/verifysession/impl/src/main/res/values-ro/translations.xml @@ -16,8 +16,9 @@ "Confirmați că emoji-urile de mai jos corespund cu cele afișate pe dispozitivul celuilalt utilizator." "Confirmați că numerele de mai jos se potrivesc cu cele afișate în cealaltă sesiune." "Comparați numerele" - "Noua dumneavoastră sesiune este acum verificată. Are acces la mesajele dumneavoastră criptate, iar alți utilizatori vă vor vedea ca fiind de încredere." + "Noua dumneavoastră sesiune este acum verificată. Are acces la mesajele dumneavoastră criptate, iar ceilalti utilizatori vă vor vedea ca fiind de încredere." "Acum puteți avea încredere în identitatea acestui utilizator atunci când trimiteți sau primiți mesaje." + "Dispozitiv verificat" "Introduceți cheia de recuperare" "Fie cererea a expirat, cererea a fost respinsă, fie a existat o nepotrivire de verificare." "Demonstrați-vă identitatea pentru a accesa mesaje anterioare criptate." @@ -44,7 +45,7 @@ "Pentru o securitate suplimentară, un alt utilizator dorește să vă verifice identitatea. Vi se va afișa un set de emoji-uri pentru comparație." "Ar trebui să vedeți o fereastră pop-up pe celălalt dispozitiv. Începeți verificarea de acolo acum." "Începeți verificarea pe celălalt dispozitiv" - "Se așteaptă celălalt dispozitiv" + "Începeți verificarea pe celălalt dispozitiv" "Se așteaptă celălalt utilizator" "După acceptare, veți putea continua verificarea." "Acceptați cererea de a începe procesul de verificare în cealaltă sesiune pentru a continua." diff --git a/features/verifysession/impl/src/main/res/values-ru/translations.xml b/features/verifysession/impl/src/main/res/values-ru/translations.xml index ace2354837..d29cdadf84 100644 --- a/features/verifysession/impl/src/main/res/values-ru/translations.xml +++ b/features/verifysession/impl/src/main/res/values-ru/translations.xml @@ -11,13 +11,14 @@ "Использовать другое устройство" "Ожидание на другом устройстве…" "Похоже, что-то не так. Время ожидания запроса либо истекло, либо запрос был отклонен." - "Убедитесь, что приведенные ниже емоджи совпадают с емоджи показанными во время другого сеанса." + "Убедитесь, что приведенные ниже эмодзи совпадают с эмодзи показанными на другом устройстве." "Сравните емодзи" "Убедитесь, что указанные ниже эмодзи соответствуют тем, которые отображаются на устройстве другого пользователя." "Убедитесь, что приведенные ниже числа совпадают с цифрами, показанными в другом сеансе." "Сравните числа" - "Ваш новый сеанс подтвержден. У него есть доступ к вашим зашифрованным сообщениям, и другие пользователи увидят его как доверенное." + "Теперь вы можете читать или отправлять сообщения безопасно в другом вашем устройстве." "Теперь вы можете доверять этому пользователя при отправке или получении сообщений." + "Устройство проверено" "Введите ключ восстановления" "Время ожидания подтверждения истекло, запрос был отклонён, или при подтверждении произошло несоответствие." "Чтобы получить доступ к зашифрованной истории сообщений, докажите, что это вы." @@ -44,7 +45,7 @@ "Для дополнительной безопасности другой пользователь хочет проверить вашу личность. Вам будет показан набор эмодзи для сравнения." "Вы должны увидеть всплывающее окно на другом устройстве. Начните проверку оттуда прямо сейчас." "Начать проверку на другом устройстве" - "Ожидание другого устройства" + "Начать проверку на другом устройстве" "Ожидание другого пользователя" "После одобрения вы сможете продолжить проверку." "Чтобы продолжить, примите запрос на запуск процесса подтверждения в другом сеансе." diff --git a/libraries/push/impl/src/main/res/values-et/translations.xml b/libraries/push/impl/src/main/res/values-et/translations.xml index b16f99a8a2..45d8e3c8c8 100644 --- a/libraries/push/impl/src/main/res/values-et/translations.xml +++ b/libraries/push/impl/src/main/res/values-et/translations.xml @@ -64,7 +64,10 @@ "Blokeeritud kasutajad" "Vali hetkel kasutatava tõuketeenuste pakkuja nimi." "Tõuketeenuste pakkujaid pole valitud." + "Praegune tõuketeenuste pakkuja on %1$s ja praegune levitaja on %2$s. Aga levitajat %3$s ei leidu - kas võib olla, et rakendus on eemaldatud?" + "Praegune tõuketeenuste pakkuja on %1$s, aga ühtegi levitajat pole seadistatud." "Hetkel kasutatav tõuketeenuste pakkuja: %1$s." + "Praegune tõuketeenuste pakkuja: %1$s (%2$s)" "Hetkel kasutatav tõuketeenuste pakkuja" "Palun taga selle rakenduse jaoks on seadistatud vähemalt üks tõuketeenuste pakkuja." "Ühtegi tõuketeenuste pakkujat ei leidu." diff --git a/libraries/push/impl/src/main/res/values-fr/translations.xml b/libraries/push/impl/src/main/res/values-fr/translations.xml index 8bf165e79a..5324597f8b 100644 --- a/libraries/push/impl/src/main/res/values-fr/translations.xml +++ b/libraries/push/impl/src/main/res/values-fr/translations.xml @@ -64,7 +64,10 @@ "Utilisateurs bloqués" "Obtenir le nom du fournisseur de Push actuel." "Aucun fournisseur de Push n’est sélectionné." + "Fournisseur de Push actuel: %1$s et distributeur actuel: %2$s. Mais le distributeur %3$s est introuvable. L’application a peut-être été désinstallée?" + "Fournisseur de Push actuel: %1$s, mais aucun distributeur n’a été configuré." "Fournisseur de Push actuel : %1$s." + "Fournisseur de Push actuel: %1$s (%2$s)" "Fournisseur de Push actuel" "Vérifier que l’application possède au moins un fournisseur de Push." "Aucun fournisseur de Push n’a été trouvé." diff --git a/libraries/push/impl/src/main/res/values-nb/translations.xml b/libraries/push/impl/src/main/res/values-nb/translations.xml index 1be74244aa..08c327acdb 100644 --- a/libraries/push/impl/src/main/res/values-nb/translations.xml +++ b/libraries/push/impl/src/main/res/values-nb/translations.xml @@ -54,6 +54,9 @@ "Bakgrunnssynkronisering" "Google Services" "Ingen gyldige Google Play-tjenester funnet. Det kan hende at varsler ikke fungerer som de skal." + "Sjekker blokkerte brukere" + "Ingen brukere er blokkert." + "Blokkerte brukere" "Få navnet på den nåværende tilbyderen." "Ingen push-leverandører er valgt." "Gjeldende push-leverandør: %1$s." diff --git a/libraries/push/impl/src/main/res/values-ro/translations.xml b/libraries/push/impl/src/main/res/values-ro/translations.xml index 00986e689a..7a5bcf2f06 100644 --- a/libraries/push/impl/src/main/res/values-ro/translations.xml +++ b/libraries/push/impl/src/main/res/values-ro/translations.xml @@ -54,9 +54,21 @@ "Sincronizare în fundal" "Servicii Google" "Nu au fost găsite servicii Google Play valide. Este posibil ca notificările să nu funcționeze corect." + "Se verifică utilizatorii blocați" + "Vizualizați utilizatorii blocați" + "Niciun utilizator nu este blocat." + + "Ai blocat%1$d utilizator. Nu veți primi notificări pentru acest utilizator." + "Ai blocat%1$d utilizatori. Nu veți primi notificări pentru acești utilizatori." + "Ai blocat%1$d utilizatori. Nu veți primi notificări pentru acești utilizatori." + + "Utilizatori blocați" "Obțineți numele furnizorului curent." "Niciun furnizor push selectat." + "Furnizorul actual de push: %1$s și distribuitorul actual: %2$s. Dar distribuitorul %3$s nu este găsit. Poate că aplicația a fost dezinstalată?" + "Furnizor push actual: %1$s, dar nu au fost configurați distribuitori." "Furnizor de push actual: %1$s." + "Furnizor actual de push: %1$s (%2$s)" "Furnizor de push curent" "Asigurați-vă că aplicația are cel puțin un furnizor push." "Nu s-au găsit furnizori push." diff --git a/libraries/push/impl/src/main/res/values-ru/translations.xml b/libraries/push/impl/src/main/res/values-ru/translations.xml index 1cb9873b4f..60a9d965f0 100644 --- a/libraries/push/impl/src/main/res/values-ru/translations.xml +++ b/libraries/push/impl/src/main/res/values-ru/translations.xml @@ -60,9 +60,21 @@ "Фоновая синхронизация" "Сервисы Google" "Не найдены действующие службы Google Play. Уведомления могут работать некорректно." + "Проверка заблокированных пользователей" + "Просмотреть заблокированных пользователей" + "Ни один пользователь не заблокирован." + + "Вы заблокировали пользователя %1$d. Вы не будете получать уведомления от этого пользователей." + "Вы заблокировали пользователей %1$d. Вы не будете получать уведомления от этих пользователей." + "Вы заблокировали пользователей %1$d. Вы не будете получать уведомления от этих пользователей." + + "Заблокированные пользователи" "Получение имени текущего поставщика." "Поставщики push-уведомлений не выбраны." + "Текущий поставщик push-уведомлений: %1$s и текущий дистрибьютор: %2$s . Но дистрибьютор %3$s не найдено. Возможно, приложение было удалено?" + "Текущий поставщик push-уведомлений: %1$s , но ни один дистрибьютор не был настроен." "Текущий поставщик push-уведомлений: %1$s." + "Текущий поставщик push-уведомлений: %1$s (%2$s)" "Текущий поставщик push-уведомлений" "Убедитесь, что у приложения есть хотя бы один поставщик push-сообщений." "Поставщики push-уведомлений не найдены." diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 8e9da34b73..45a3235ad5 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -64,7 +64,10 @@ "Blocked users" "Get the name of the current provider." "No push providers selected." + "Current push provider: %1$s and current distributor: %2$s. But the distributor %3$s is not found. Maybe the application has been uninstalled?" + "Current push provider: %1$s, but no distributors have been configured." "Current push provider: %1$s." + "Current push provider: %1$s (%2$s)" "Current push provider" "Ensure that the application supports at least one push provider." "No push provider support found." diff --git a/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml b/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml index 05bce25dfd..00d2674ed7 100644 --- a/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml +++ b/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml @@ -1,5 +1,6 @@ + "Minimize" "Favorite" "Favorited" diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index d4c96c52db..905144da88 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -110,6 +110,7 @@ "Halda kasutajakontot" "Halda seadmeid" "Saada sõnum" + "Minimeeri" "Edasi" "Ei" "Mitte praegu" diff --git a/libraries/ui-strings/src/main/res/values-fr/translations.xml b/libraries/ui-strings/src/main/res/values-fr/translations.xml index 9d3555baaa..3dce6a923c 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -110,6 +110,7 @@ "Gérer le compte" "Gérez les sessions" "Message" + "Minimiser" "Suivant" "Non" "Pas maintenant" @@ -225,6 +226,7 @@ Raison : %1$s." "Installer l’APK" "Cet identifiant Matrix est introuvable, il est donc possible que l’invitation ne soit pas reçue." "Quitter le salon…" + "En train de quitter l’espace" "Clair" "Ligne copiée dans le presse-papiers" "Lien copié dans le presse-papiers" diff --git a/libraries/ui-strings/src/main/res/values-nb/translations.xml b/libraries/ui-strings/src/main/res/values-nb/translations.xml index 24594c782e..eb2f8cc5b1 100644 --- a/libraries/ui-strings/src/main/res/values-nb/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nb/translations.xml @@ -2,6 +2,7 @@ "Legg til reaksjon: %1$s" "Profilbilde" + "Minimer meldingstekstfeltet" "Slett" "%1$d siffer angitt" @@ -10,6 +11,7 @@ "Rediger avatar" "Den fullstendige adressen vil være %1$s" "Krypteringsdetaljer" + "Utvid meldingstekstfeltet" "Skjul passord" "Bli med i samtale" "Hopp til bunnen" @@ -87,6 +89,7 @@ "Aktiver" "Avslutt avstemning" "Skriv inn PIN-koden" + "Fullfør" "Glemt passordet?" "Videresend" "Gå tilbake" @@ -101,6 +104,7 @@ "Forlat" "Forlat samtalen" "Forlat rommet" + "Forlat område" "Last inn mer" "Administrer konto" "Administrer enheter" @@ -161,10 +165,14 @@ "Oppgradering tilgjengelig" "Om" "Retningslinjer for akseptabel bruk" + "Legg til en konto" + "Legg til en annen konto" "Legger til bildetekst" "Avanserte innstillinger" "et bilde" "Analyse" + "Du forlot rommet" + "Du ble logget ut av økten" "Utseende" "Lyd" "Blokkerte brukere" @@ -176,9 +184,11 @@ "Oppretter rom …" "Forespørsel kansellert" "Forlot rommet" + "Forlot område" "Invitasjon avslått" "Mørk" "Dekrypteringsfeil" + "Beskrivelse" "Alternativer for utviklere" "Enhets-ID" "Direkte chat" @@ -287,17 +297,21 @@ "Søkeresultater" "Sikkerhet" "Sett av" + "Velg en konto" "Sendt til" "Sender…" "Kunne ikke sende" "Sendt" "Server støttes ikke" + "Serveren er ikke tilgjengelig" "URL-adresse til server" "Innstillinger" + "Del område" "Delt posisjon" "Logger av" "Noe gikk galt" "Vi har støtt på et problem. Vennligst prøv igjen." + "Område" "%1$d Område" "%1$d Områder" @@ -332,6 +346,12 @@ "Verifiser identiteten" "Verifiser bruker" "Video" + "Høy kvalitet" + "Beste kvalitet, men større filstørrelse" + "Lav kvalitet" + "Raskeste opplastingshastighet og minste filstørrelse" + "Standard kvalitet" + "Balansen mellom kvalitet og opplastingshastighet" "Talemelding" "Venter…" "Venter på denne meldingen" @@ -346,6 +366,10 @@ Er du sikker på at du vil fortsette?" "Dobbeltsjekk denne lenken" + "Velg standardkvaliteten på videoene du laster opp." + "Kvalitet på videoopplasting" + "Maksimal tillatt filstørrelse er: %1$s" + "Filstørrelsen er for stor til å kunne lastes opp" "Rommet er rapportert" "Rapportert og forlatt rommet" "Bekreftelse" @@ -354,6 +378,11 @@ Er du sikker på at du vil fortsette?" "Advarsel" "Endringene dine er ikke lagret. Er du sikker på at du vil gå tilbake?" "Lagre endringer?" + "Maksimal tillatt filstørrelse er: %1$s" + "Velg kvaliteten på videoen du vil laste opp." + "Velg kvalitet for videoopplasting" + "Søk etter emojier" + "Du er allerede logget inn på denne enheten som %1$s." "Hjemmeserveren din må oppgraderes for å støtte Matrix Authentication Service og kontooppretting." "Opprettelse av permalenken mislyktes" "%1$s kunne ikke laste inn kartet. Prøv igjen senere." @@ -404,6 +433,7 @@ Er du sikker på at du vil fortsette?" "Meldingen din ble ikke sendt fordi %1$s ikke har bekreftet alle enhetene" "En eller flere av enhetene dine er ikke verifisert. Du kan sende meldingen likevel, eller du kan avbryte og prøve igjen senere etter at du har verifisert alle enhetene dine." "Meldingen din ble ikke sendt fordi du ikke har verifisert en eller flere av enhetene dine" + "Rediger administratorer eller eiere" "Kunne ikke behandle medier for opplasting, vennligst prøv igjen." "Kunne ikke hente brukerdetaljer" "Melding i %1$s" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index ee2533cafa..9fe88da203 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -44,7 +44,7 @@ "Îndepărtați reacția %1$s" "Avatarul camerei" "Trimiteți fișiere" - "Acțiune cu termen limită necesară" + "Acțiune limitată în timp necesară, aveți un minut pentru a verifica" "Afișați parola" "Începeți un apel" "Cameră terminată" @@ -107,10 +107,12 @@ "Părăsiți" "Părăsiți conversația" "Părăsiți camera" + "Părăsiți spațiul" "Încărcați mai mult" "Administrare cont" "Gestionare dispozitive" "Mesaj" + "Minimizați" "Următorul" "Nu" "Nu acum" @@ -167,6 +169,8 @@ "Upgrade disponibil" "Despre" "Politică de utilizare rezonabilă" + "Adăugați un cont" + "Adăugați un alt cont" "Adăugare descriere" "Setări avansate" "o imagine" @@ -184,9 +188,12 @@ "Se creează camera…" "Cerere anulată" "Ați parăsit camera" + "S-a părăsit spațiul" "Invitația a fost refuzată" "Întunecat" "Eroare de decriptare" + "Descriere" + "Deselectați tot" "Opțiuni programator" "ID-ul dispozitivului" "Chat direct" @@ -221,6 +228,7 @@ Motiv:%1$s." "Instalați APK" "Nu am putut valida ID-ul Matrix al acestui utilizator. Este posibil ca invitația să nu fi fost trimisă." "Se părăsește conversația" + "Se părăsește spațiul" "Deschis" "Linie copiată în clipboard" "Linkul a fost copiat în clipboard" @@ -245,6 +253,7 @@ Motiv:%1$s." "%1$s (%2$s)" "Niciun rezultat" "Fără nume de cameră" + "Fără nume de spațiu" "Necriptat" "Deconectat" "Licențe open source" @@ -301,14 +310,18 @@ Motiv:%1$s." "Rezultatele căutării" "Securitate" "Văzut de" + "Selectați un cont" + "Selectați tot" "Trimiteți către" "Se trimite…" "Trimiterea a eșuat" "Trimis" ". " "Serverul nu este compatibil" + "Serverul nu poate fi accesat" "Adresa URL a serverului" "Setări" + "Partajați spațiul" "Locație partajată" "Deconectare în curs" "Ceva nu a mers bine" @@ -384,6 +397,8 @@ Sunteți sigur că doriți să continuați?" "Dimensiunea maximă permisă pentru fișiere este: %1$s" "Selectați calitatea videoclipului pe care doriți să îl încărcați." "Selectați calitatea de încărcare a videoclipurilor" + "Căutați emoticoane" + "Sunteți deja conectat pe acest dispozitiv ca %1$s." "Serverul dumneavoastră trebuie actualizat pentru a suporta serviciul de autentificare Matrix și crearea de conturi." "Crearea permalink-ului a eșuat" "%1$s nu a putut încărca harta. Vă rugăm să încercați din nou mai târziu." @@ -455,6 +470,7 @@ Sunteți sigur că doriți să continuați?" "Distribuiți această locație" "Spații pe care le-ați creat sau la care v-ați alăturat." "%1$s • %2$s" + "Spațiu %1$s" "Spații" "Mesajul nu a fost trimis deoarece identitatea verificată a lui %1$s s-a schimbat." "Mesajul nu a fost trimis deoarece %1$s nu a verificat toate dispozitivele." diff --git a/libraries/ui-strings/src/main/res/values-ru/translations.xml b/libraries/ui-strings/src/main/res/values-ru/translations.xml index d57db4ce60..5773be3e1d 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -2,6 +2,7 @@ "Добавить реакцию:%1$s" "Аватар" + "Свернуть поле текста сообщения" "Удалить" "Введена %1$d цифра" @@ -11,6 +12,7 @@ "Изменить аватар" "Полный адрес %1$s" "Сведения о шифровании" + "Развернуть поле текста сообщения" "Скрыть пароль" "Присоединиться к звонку" "Перейти вниз" @@ -42,7 +44,7 @@ "Удалить реакцию %1$s" "Аватар комнаты" "Отправить файлы" - "Требуется срочное действие" + "Требуется действие, на которое есть ограничение по времени, у вас есть одна минута для проверки" "Показать пароль" "Начать звонок" "Аватар пользователя" @@ -104,10 +106,12 @@ "Покинуть" "Покинуть беседу" "Покинуть комнату" + "Покинуть пространство" "Загрузить еще" "Настройки учетной записи" "Управление устройствами" "Сообщение" + "Свернуть" "Далее" "Нет" "Не сейчас" @@ -162,15 +166,21 @@ "Да, попробуйте еще раз" "Теперь ваш сервер поддерживает новый, более быстрый протокол. Чтобы обновить его прямо сейчас, выйдите и войдите в свою учётную запись снова. Сделав это сейчас, вы сможете избежать принудительного выхода из системы при последующем удалении старого протокола." "Доступно обновление" + "Ваши уведомления были обновлены — теперь они понятнее, быстрее и менее отвлекающие." + "Мы обновили ваши звуки" "О приложении" "Политика допустимого использования" + "Добавить аккаунт" + "Добавить другой аккаунт" "Добавление подписи" "Дополнительные настройки" "изображение" "Аналитика" "Вы покинули комнату" + "Вы вышли из сеанса" "Внешний вид" "Аудио" + "Бета-версия" "Заблокированные пользователи" "Пузыри" "Звонок начат" @@ -180,9 +190,12 @@ "Создание комнаты…" "Запрос отменен" "Покинул комнату" + "Покинуть пространство" "Приглашение отклонено" "Тёмное" "Ошибка расшифровки" + "Описание" + "Отменить выбор" "Для разработчика" "Идентификатор устройства" "Личный чат" @@ -217,6 +230,7 @@ "Установить APK" "Идентификатор Matrix ID не найден, приглашение может быть не получено." "Покидание комнаты" + "Покинуть пространство" "Светлое" "Строка скопирована в буфер обмена" "Ссылка скопирована в буфер обмена" @@ -241,6 +255,7 @@ "%1$s (%2$s)" "Ничего не найдено" "Название комнаты отсутствует" + "Нет имени пространства" "Не зашифровано" "Не в сети" "Лицензии с открытым исходным кодом" @@ -285,6 +300,11 @@ "Комната" "Название комнаты" "например, название вашего проекта" + + "%1$d Комната" + "%1$d Комнат" + "%1$d Комнат" + "Изменения сохранены" "Сохранение" "Блокировка приложения" @@ -292,19 +312,28 @@ "Результаты поиска" "Безопасность" "Просмотрено" + "Выберите учетную запись" + "Выбрать все" "Отправить" "Отправка…" "Сбой отправки" "Отправлено" ". " "Сервер не поддерживается" + "Сервер недоступен" "Адрес сервера" "Настройки" + "Поделиться пространством" "Поделился местоположением" "Выход…" "Что-то пошло не так" "Мы столкнулись с проблемой. Пожалуйста, попробуйте еще раз." "Подпространство" + + "%1$d Пространство" + "%1$d Пространств" + "%1$d Пространств" + "Чат запускается…" "Стикер" "Успешно" @@ -367,8 +396,11 @@ "Предупреждение" "Изменения не сохранены. Вы действительно хотите вернуться?" "Сохранить изменения?" + "Максимально допустимый размер файла: %1$s" "Выберите качество видео, которое вы хотите загрузить." "Выберите качество загружаемого видео" + "Поиск эмодзи" + "Вы уже вошли на данном устройстве как %1$s." "Ваш домашний сервер необходимо обновить, чтобы он поддерживал Matrix Authentication Service и создание учётных записей." "Не удалось создать постоянную ссылку" "Не удалось загрузить карту %1$s. Пожалуйста, повторите попытку позже." @@ -401,6 +433,10 @@ "Параметры" "Удалить %1$s" "Настройки" + "Включить ответы в топике" + "Попробуйте наши последние идеи в разработке. Эти функции ещё не завершены, они могут быть нестабильны и могут измениться." + "Хотите попробовать?" + "Лаборатория" "Не удалось выбрать носитель, попробуйте еще раз." "Нажмите на сообщение и выберите “%1$s”, чтобы добавить его сюда." "Закрепите важные сообщения, чтобы их можно было легко найти" @@ -438,6 +474,10 @@ "Открыть в Google Maps" "Открыть в OpenStreetMap" "Поделиться этим местоположением" + "Пространства, которые вы создали или к которым присоединились." + "%1$s • %2$s" + "%1$s пространство" + "Пространства" "Сообщение не отправлено, потому что подтвержденная личность %1$s была сброшена." "Сообщение не отправлено, потому что %1$s не проверил одно или несколько устройств." "Сообщение не отправлено, поскольку вы не подтвердили одно или несколько своих устройств." diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 9e3d8f6035..527745898a 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -110,6 +110,7 @@ "Manage account" "Manage devices" "Message" + "Minimise" "Next" "No" "Not now" @@ -164,6 +165,8 @@ "Yes, try again" "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later." "Upgrade available" + "Your notification ping has been updated—clearer, quicker, and less disruptive." + "We’ve refreshed your sounds" "About" "Acceptable use policy" "Add an account" @@ -176,6 +179,7 @@ "You were logged out of the session" "Appearance" "Audio" + "Beta" "Blocked users" "Bubbles" "Call started" @@ -225,6 +229,7 @@ Reason: %1$s." "Install APK" "This Matrix ID can\'t be found, so the invite might not be received." "Leaving room" + "Leaving space" "Light" "Line copied to clipboard" "Link copied to clipboard" @@ -421,6 +426,10 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" + "Enable thread replies" + "Try out our latest ideas in development. These features are not finalised; they may be unstable, may change." + "Feeling experimental?" + "Labs" "Failed selecting media, please try again." "Press on a message and choose “%1$s” to include here." "Pin important messages so that they can be easily discovered" diff --git a/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png b/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png new file mode 100644 index 0000000000..dd31d1913c --- /dev/null +++ b/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51ead4787c405e5d05a37ae5c22b655da0bb32b07de9b5b57de98e42c30f6bac +size 60346 diff --git a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_32_de.png b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_32_de.png index 707e02b860..323bc366ef 100644 --- a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_32_de.png +++ b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_32_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d51f365f53e6d513995ff06dd428b2093bd3410e50ccd0f140f9b187ed72932b -size 13055 +oid sha256:2b02cde7ac34031dac3ab62cbc88bac96475c287aa7edbe7c057edfbfbfbc91f +size 23478 diff --git a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_33_de.png b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_33_de.png index 86e74552cf..707e02b860 100644 --- a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_33_de.png +++ b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_33_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be3903803196a109c756058a33f278a268013e953073427afe1469992c921e8f -size 18424 +oid sha256:d51f365f53e6d513995ff06dd428b2093bd3410e50ccd0f140f9b187ed72932b +size 13055 diff --git a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_34_de.png b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_34_de.png index 349100c47f..86e74552cf 100644 --- a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_34_de.png +++ b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_34_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7447fa97dde37796951804ff2e19a9e2fcd83f9ef0acd62d8591fca467a6c59f -size 15918 +oid sha256:be3903803196a109c756058a33f278a268013e953073427afe1469992c921e8f +size 18424 diff --git a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_35_de.png b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_35_de.png new file mode 100644 index 0000000000..349100c47f --- /dev/null +++ b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_35_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7447fa97dde37796951804ff2e19a9e2fcd83f9ef0acd62d8591fca467a6c59f +size 15918 diff --git a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_0_de.png b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_0_de.png index b01fd29b6e..50e54d1b1f 100644 --- a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_0_de.png +++ b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ee0972a8becd44e2536c65c379413d319bbca7925290a9c01ce365d4c136c71 -size 109740 +oid sha256:becac920640a939711f0d4d1e0f7987de42f53b3ed8ac0d0c4758ea1e62a53ea +size 130575 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_0_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_0_de.png index fc5a3aca3c..fd00f875fe 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_0_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d094a27accfb3c562af33e4b510d3bc5ff9aef94799573d30354dddb411d920 -size 15583 +oid sha256:fe4e5c4f1defe3b99adcf563eb389c943f93d5417f2344eff2312f2b809991c7 +size 15572 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_1_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_1_de.png index 388998b224..a56d30a522 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_1_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49190b524bbf7e2c489b882ced36d26fcf7019fbedbcefec635a6757316e334e -size 18302 +oid sha256:58812339f1ac01175b64421d0af685330c4bd95186eff5213194e573deeaa443 +size 18292 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_2_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_2_de.png index 6a17df2a16..8a3fdd24f4 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_2_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3686336e9bac54a626c0a2cf704d460e695a79f56925a631018a1d7e3c3a4d97 -size 45967 +oid sha256:565857c30ef349022e9cddfcd892a481858ba83bc3dacf884ae37be964fe327b +size 46496 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_3_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_3_de.png index 19bbf7cd4c..94f10f54ac 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_3_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbe09f5baf21e50542e9eb1e889630419d3495247416d8698dca43c6427e3573 -size 45916 +oid sha256:5424035b81a1cf082a6a56450bfc444810ffb7d0af87d0803e99151c9cdb3cb4 +size 46000 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_4_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_4_de.png index 97bb338e38..a671d930f2 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_4_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71486e65a7010fb74dc43c7a7e013e0a9c2fd38750f77410a4ba67232b50fce7 -size 38942 +oid sha256:bc606ced38ea3dc316cdbb08198cd265c53331437e687bca62972b2152f15fbc +size 38410 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_5_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_5_de.png index b8a80e79db..630c80c9c2 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_5_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b58ce117dde4af11c16ddf460b87c2d1030631ef1038ee6f5824d017e75869fe -size 45568 +oid sha256:9d8d61fba64acc6022d0c12b931012995f428384434f10b65f5ffacf0f7c914e +size 45226 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_6_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_6_de.png index cb1c9985fb..f942304d6f 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_6_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2844a4696db06085edcce66b8c4de5c89d2093ec4df216b09424b99517ebe1d6 -size 41043 +oid sha256:def46d1907ba93766cf6b4d465840820221800d2d4e34a14b757697d73b17623 +size 44009 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_7_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_7_de.png index b1797a1489..bc853d286e 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_7_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7723d8a70239909f1f11e3a02b5031d432454acc67b171e0ece591abb831fbb5 -size 35685 +oid sha256:ec8a73647a8cadd203006313fb3baa79e27f9e8faaef991d7e37c0faccc67281 +size 42259 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_8_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_8_de.png index ff09556f6d..01c57b8085 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_8_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b39e08d2579a63b5eb7a6cb9eb9c1c0ef5a737d017419994712a50c6d74f732a -size 15510 +oid sha256:0e86c1032701041744144e88185238129ed824b2e4cb0c4992d6cceae2322442 +size 20060 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png new file mode 100644 index 0000000000..7420e45d7a --- /dev/null +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:413b9e7e2db4235a96bb1aead3855bfcc4461a05e84b2c75fdb610a80b26fcf9 +size 26711 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_2_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_2_de.png index 551d14618c..8da7a35121 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_2_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8757b8898722de0ea2537ccc03c29d7b821842876b798a7bfd0005ef404538a9 -size 47232 +oid sha256:96c9e6799d9e2f50e095544ba92bf17012bd73b8d5e300954cf574992256e8d9 +size 55900 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_3_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_3_de.png index cd7399152e..464ab7f7c4 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_3_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:856a18b6f0b4a2098b81013617b479e94c4bac5f356ae8ead9032a2ade653a11 -size 45947 +oid sha256:480354594a3236a4d963073b98125cd4d57a6980e957f7884f28d285dace91c6 +size 55043 diff --git a/screenshots/de/features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_de.png b/screenshots/de/features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_de.png index a0b071fdc4..9741448fa7 100644 --- a/screenshots/de/features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_de.png +++ b/screenshots/de/features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:583703525dc6b252fe7042d26b4ea3af06346eb971a78360db3a1fdf66ea995d -size 15110 +oid sha256:6d4b8d2bb20ecf61d7f288b25b542d3441335c765d47d21282a9464a591da12b +size 25133 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png index f86f0e4348..f5576fd8a3 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a585cdbb479e4ab2aa53f9d0358a9a2068d2607094558f176a83bd2efcee48b -size 46009 +oid sha256:bcc6e14373fd9da583310dbbc759d0286a3b8ae36ddb0284709e3b937eb82d45 +size 48300 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png index f86f0e4348..f5576fd8a3 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a585cdbb479e4ab2aa53f9d0358a9a2068d2607094558f176a83bd2efcee48b -size 46009 +oid sha256:bcc6e14373fd9da583310dbbc759d0286a3b8ae36ddb0284709e3b937eb82d45 +size 48300 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png index d119111de8..f07f83f945 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad9081355cb2897a5bf759d6f73920f5d9a1ae6d0ff7025df7c1200c4f25ecda -size 40869 +oid sha256:92f2c1c5cac7875798293f1daff35c4753bc1aec81ec42101288bab269c633e2 +size 43345 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png index e56aa1ca9f..aa41993ba1 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5615a84e510c1ee49321fba1bb2620042d32aa67d5197b8b88a642bf1c3edd9 -size 36232 +oid sha256:f309d9cdb5c9b5aec9f9736b045895c33a2db5873207c9b4f410b429e3cb4c2d +size 36239 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png index 39db3ce4fa..badc9d4606 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f983de6f7ed75b02a491fb7d4a9341b40a1f367d1e298a77ff8baf9b475a75c3 -size 30032 +oid sha256:0c3c0a2ec93e0ccabcb1b529dfa6fb117ea572719670dec770a31789d32db131 +size 27229 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_0_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_0_de.png new file mode 100644 index 0000000000..738e01fe3f --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7d03c199e22eb0f0b6e34b42efc65d138ac32c743631f65553ba3497ded0362 +size 17452 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_1_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_1_de.png new file mode 100644 index 0000000000..4f234befc6 --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06ba4b65baf7638599ce0adefe25c3836c322168c5e0cdfe8f93162b2d3b3b8a +size 13462 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_de.png new file mode 100644 index 0000000000..388eaba735 --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96aef4e08d3d1d21701a8c18832f60eca0317c2ced0c4f06d8d9a71231434bbd +size 24579 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_de.png new file mode 100644 index 0000000000..866b8156d9 --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52beb69cc61ef5a526b371c28859e9fd290ef709d2ee01a60a5343f3397acf52 +size 19003 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_de.png new file mode 100644 index 0000000000..a59afa345c --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91fd58d1cf3f872884f8cbdebff3edbdbe4c2989d8e8604dfe1d0fa82af7c8c +size 16305 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_de.png new file mode 100644 index 0000000000..d8a861df8c --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f41fc24c60b5f9df31b5a92e6ea02dd1d7c107546879d69110703da6a82a014c +size 36050 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_de.png new file mode 100644 index 0000000000..004355afe2 --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3d4a5779c3c7e491a75ce23e9c89cda51e7ab255fc8e652f1e64801c3d8afb4 +size 42972 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_de.png new file mode 100644 index 0000000000..004355afe2 --- /dev/null +++ b/screenshots/de/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3d4a5779c3c7e491a75ce23e9c89cda51e7ab255fc8e652f1e64801c3d8afb4 +size 42972 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index ea8cc5e068..b29adf506e 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,79 +1,79 @@ // Generated file, do not edit export const screenshots = [ ["en","en-dark","de",], -["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20360,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20364,], ["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_0_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_0_en",0,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20360,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20360,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20360,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20360,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20360,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20360,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20360,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20360,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20360,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20360,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20360,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20364,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20364,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20364,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20364,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20364,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20364,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20364,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20364,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20364,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20364,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20364,], ["features.login.impl.accountprovider_AccountProviderView_Day_0_en","features.login.impl.accountprovider_AccountProviderView_Night_0_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_1_en","features.login.impl.accountprovider_AccountProviderView_Night_1_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_2_en","features.login.impl.accountprovider_AccountProviderView_Night_2_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_3_en","features.login.impl.accountprovider_AccountProviderView_Night_3_en",0,], -["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20360,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20360,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20364,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20364,], ["features.messages.impl.actionlist_ActionListViewContent_Day_0_en","features.messages.impl.actionlist_ActionListViewContent_Night_0_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20360,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20364,], ["features.messages.impl.actionlist_ActionListViewContent_Day_1_en","features.messages.impl.actionlist_ActionListViewContent_Night_1_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20360,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20360,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20360,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20360,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20360,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20360,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20360,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20360,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20360,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20360,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20360,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20360,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20360,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20360,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20364,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20364,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20364,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20364,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20364,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20364,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20364,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20364,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20364,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20364,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20364,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20364,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20364,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20364,], ["libraries.designsystem.components_Announcement_Day_0_en","libraries.designsystem.components_Announcement_Night_0_en",0,], -["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20360,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20364,], ["libraries.designsystem.components.async_AsyncActionView_Day_0_en","libraries.designsystem.components.async_AsyncActionView_Night_0_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20360,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20364,], ["libraries.designsystem.components.async_AsyncActionView_Day_2_en","libraries.designsystem.components.async_AsyncActionView_Night_2_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20360,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20364,], ["libraries.designsystem.components.async_AsyncActionView_Day_4_en","libraries.designsystem.components.async_AsyncActionView_Night_4_en",0,], -["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20360,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20364,], ["libraries.designsystem.components.async_AsyncIndicatorFailure_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorFailure_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncIndicatorLoading_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorLoading_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncLoading_Day_0_en","libraries.designsystem.components.async_AsyncLoading_Night_0_en",0,], -["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20360,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20364,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_0_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_0_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_1_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_1_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_2_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_2_en",0,], @@ -83,19 +83,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20360,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20360,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20364,], +["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20364,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_1_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_2_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_2_en",0,], -["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20360,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20364,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -242,146 +242,147 @@ export const screenshots = [ ["libraries.designsystem.modifiers_BackgroundVerticalGradientEnterprise_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradientEnterprise_Night_0_en",0,], ["libraries.designsystem.modifiers_BackgroundVerticalGradient_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradient_Night_0_en",0,], ["libraries.designsystem.components_Badge_Day_0_en","libraries.designsystem.components_Badge_Night_0_en",0,], -["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20360,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20364,], +["libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en","libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en",0,], ["libraries.designsystem.components_BigIcon_Day_0_en","libraries.designsystem.components_BigIcon_Night_0_en",0,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20360,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20360,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20364,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20364,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportView_Day_0_en","features.rageshake.impl.bugreport_BugReportView_Night_0_en",20360,], -["features.rageshake.impl.bugreport_BugReportView_Day_1_en","features.rageshake.impl.bugreport_BugReportView_Night_1_en",20360,], -["features.rageshake.impl.bugreport_BugReportView_Day_2_en","features.rageshake.impl.bugreport_BugReportView_Night_2_en",20360,], -["features.rageshake.impl.bugreport_BugReportView_Day_3_en","features.rageshake.impl.bugreport_BugReportView_Night_3_en",20360,], -["features.rageshake.impl.bugreport_BugReportView_Day_4_en","features.rageshake.impl.bugreport_BugReportView_Night_4_en",20360,], +["features.rageshake.impl.bugreport_BugReportView_Day_0_en","features.rageshake.impl.bugreport_BugReportView_Night_0_en",20364,], +["features.rageshake.impl.bugreport_BugReportView_Day_1_en","features.rageshake.impl.bugreport_BugReportView_Night_1_en",20364,], +["features.rageshake.impl.bugreport_BugReportView_Day_2_en","features.rageshake.impl.bugreport_BugReportView_Night_2_en",20364,], +["features.rageshake.impl.bugreport_BugReportView_Day_3_en","features.rageshake.impl.bugreport_BugReportView_Night_3_en",20364,], +["features.rageshake.impl.bugreport_BugReportView_Day_4_en","features.rageshake.impl.bugreport_BugReportView_Night_4_en",20364,], ["libraries.designsystem.atomic.molecules_ButtonColumnMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonColumnMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20360,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20360,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20364,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20364,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20360,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20360,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20360,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20360,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20360,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_0_en","features.changeroommemberroles.impl_ChangeRolesView_Night_0_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_10_en","features.changeroommemberroles.impl_ChangeRolesView_Night_10_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_11_en","features.changeroommemberroles.impl_ChangeRolesView_Night_11_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_12_en","features.changeroommemberroles.impl_ChangeRolesView_Night_12_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_1_en","features.changeroommemberroles.impl_ChangeRolesView_Night_1_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_2_en","features.changeroommemberroles.impl_ChangeRolesView_Night_2_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_3_en","features.changeroommemberroles.impl_ChangeRolesView_Night_3_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_4_en","features.changeroommemberroles.impl_ChangeRolesView_Night_4_en",20360,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20364,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20364,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20364,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20364,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20364,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_0_en","features.changeroommemberroles.impl_ChangeRolesView_Night_0_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_10_en","features.changeroommemberroles.impl_ChangeRolesView_Night_10_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_11_en","features.changeroommemberroles.impl_ChangeRolesView_Night_11_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_12_en","features.changeroommemberroles.impl_ChangeRolesView_Night_12_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_1_en","features.changeroommemberroles.impl_ChangeRolesView_Night_1_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_2_en","features.changeroommemberroles.impl_ChangeRolesView_Night_2_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_3_en","features.changeroommemberroles.impl_ChangeRolesView_Night_3_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_4_en","features.changeroommemberroles.impl_ChangeRolesView_Night_4_en",20364,], ["features.changeroommemberroles.impl_ChangeRolesView_Day_5_en","features.changeroommemberroles.impl_ChangeRolesView_Night_5_en",0,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_6_en","features.changeroommemberroles.impl_ChangeRolesView_Night_6_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_7_en","features.changeroommemberroles.impl_ChangeRolesView_Night_7_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_8_en","features.changeroommemberroles.impl_ChangeRolesView_Night_8_en",20360,], -["features.changeroommemberroles.impl_ChangeRolesView_Day_9_en","features.changeroommemberroles.impl_ChangeRolesView_Night_9_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_0_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_1_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_2_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_3_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_4_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_5_en",20360,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_6_en",20360,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_6_en","features.changeroommemberroles.impl_ChangeRolesView_Night_6_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_7_en","features.changeroommemberroles.impl_ChangeRolesView_Night_7_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_8_en","features.changeroommemberroles.impl_ChangeRolesView_Night_8_en",20364,], +["features.changeroommemberroles.impl_ChangeRolesView_Day_9_en","features.changeroommemberroles.impl_ChangeRolesView_Night_9_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_0_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_1_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_2_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_3_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_4_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_5_en",20364,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_6_en",20364,], ["features.login.impl.changeserver_ChangeServerView_Day_0_en","features.login.impl.changeserver_ChangeServerView_Night_0_en",0,], -["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20360,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20360,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20360,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20360,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20364,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20364,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20364,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20364,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20360,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20364,], ["libraries.designsystem.theme.components_Checkboxes_Toggles_en","",0,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20360,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20360,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20360,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20360,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20360,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20360,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20360,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20364,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20364,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20364,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20364,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20364,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20364,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20364,], ["libraries.designsystem.theme.components_CircularProgressIndicator_Progress_Indicators_en","",0,], ["libraries.designsystem.components_ClickableLinkText_Text_en","",0,], ["libraries.designsystem.theme_ColorAliases_Day_0_en","libraries.designsystem.theme_ColorAliases_Night_0_en",0,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20360,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20360,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20360,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20364,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20364,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20364,], ["libraries.textcomposer_ComposerModeView_Day_1_en","libraries.textcomposer_ComposerModeView_Night_1_en",0,], ["libraries.textcomposer_ComposerModeView_Day_2_en","libraries.textcomposer_ComposerModeView_Night_2_en",0,], ["libraries.textcomposer_ComposerModeView_Day_3_en","libraries.textcomposer_ComposerModeView_Night_3_en",0,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20360,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20360,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20360,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20360,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20360,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20360,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20364,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20364,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20364,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20364,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20364,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20364,], ["libraries.designsystem.components.dialogs_ConfirmationDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ConfirmationDialog_Day_0_en","libraries.designsystem.components.dialogs_ConfirmationDialog_Night_0_en",0,], ["features.networkmonitor.api.ui_ConnectivityIndicatorView_Day_0_en","features.networkmonitor.api.ui_ConnectivityIndicatorView_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_CounterAtom_Day_0_en","libraries.designsystem.atomic.atoms_CounterAtom_Night_0_en",0,], -["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20360,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20360,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20360,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20360,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20360,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20360,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20360,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20360,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20360,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20360,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20360,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20360,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20360,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20360,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20360,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20360,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20360,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20360,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20360,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20360,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20364,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20364,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20364,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20364,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20364,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20364,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20364,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20364,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20364,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20364,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20364,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20364,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20364,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20364,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20364,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20364,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20364,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20364,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20364,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20364,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_1_en",0,], -["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20360,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20360,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20360,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20360,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20360,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20360,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20360,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20364,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20364,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20364,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20364,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20364,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20364,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20364,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_0_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_0_en",0,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20360,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20360,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20360,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20364,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20364,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20364,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_4_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_4_en",0,], -["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20360,], -["features.home.impl.components_DefaultRoomListTopBarMultiAccount_Day_0_en","features.home.impl.components_DefaultRoomListTopBarMultiAccount_Night_0_en",20360,], -["features.home.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en","features.home.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en",20360,], -["features.home.impl.components_DefaultRoomListTopBar_Day_0_en","features.home.impl.components_DefaultRoomListTopBar_Night_0_en",20360,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20364,], +["features.home.impl.components_DefaultRoomListTopBarMultiAccount_Day_0_en","features.home.impl.components_DefaultRoomListTopBarMultiAccount_Night_0_en",20364,], +["features.home.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en","features.home.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en",20364,], +["features.home.impl.components_DefaultRoomListTopBar_Day_0_en","features.home.impl.components_DefaultRoomListTopBar_Night_0_en",20364,], ["features.licenses.impl.details_DependenciesDetailsView_Day_0_en","features.licenses.impl.details_DependenciesDetailsView_Night_0_en",0,], -["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20360,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20360,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20360,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20360,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20360,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20360,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20360,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20364,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20364,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20364,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20364,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20364,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20364,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20364,], ["libraries.designsystem.theme.components_DialogWithDestructiveButton_Dialog_with_destructive_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithOnlyMessageAndOkButton_Dialog_with_only_message_and_ok_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithThirdButton_Dialog_with_third_button_Dialogs_en","",0,], @@ -396,18 +397,18 @@ export const screenshots = [ ["libraries.designsystem.text_DpScale_1_0f__en","",0,], ["libraries.designsystem.text_DpScale_1_5f__en","",0,], ["libraries.designsystem.theme.components_DropdownMenuItem_Menus_en","",0,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20360,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20360,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20360,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20360,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20360,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20360,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20360,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20360,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20360,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20360,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20360,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20360,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20364,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20364,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20364,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20364,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20364,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20364,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20364,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20364,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20364,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20364,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20364,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20364,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -418,13 +419,14 @@ export const screenshots = [ ["libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Night_0_en",0,], ["features.messages.impl.timeline.components.customreaction_EmojiItem_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiItem_Night_0_en",0,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20360,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20360,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20364,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20364,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en",0,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en",0,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20360,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20360,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20360,], +["libraries.ui.common.nodes_EmptyView_Day_0_en","libraries.ui.common.nodes_EmptyView_Night_0_en",0,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20364,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20364,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20364,], ["features.messages.impl.timeline.debug_EventDebugInfoView_Day_0_en","features.messages.impl.timeline.debug_EventDebugInfoView_Night_0_en",0,], ["libraries.designsystem.components_ExpandableBottomSheetLayout_en","",0,], ["libraries.featureflag.ui_FeatureListView_Day_0_en","libraries.featureflag.ui_FeatureListView_Night_0_en",0,], @@ -443,41 +445,41 @@ export const screenshots = [ ["libraries.designsystem.theme.components_FloatingActionButton_Floating_Action_Buttons_en","",0,], ["libraries.designsystem.atomic.pages_FlowStepPage_Day_0_en","libraries.designsystem.atomic.pages_FlowStepPage_Night_0_en",0,], ["features.messages.impl.timeline.focus_FocusRequestStateView_Day_0_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_0_en",0,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20360,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20360,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20360,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20364,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20364,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20364,], ["features.messages.impl.timeline.components_FocusedEventEnterprise_Day_0_en","features.messages.impl.timeline.components_FocusedEventEnterprise_Night_0_en",0,], ["features.messages.impl.timeline.components_FocusedEvent_Day_0_en","features.messages.impl.timeline.components_FocusedEvent_Night_0_en",0,], ["libraries.textcomposer.components_FormattingOption_Day_0_en","libraries.textcomposer.components_FormattingOption_Night_0_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_0_en","features.messages.impl.forward_ForwardMessagesView_Night_0_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_1_en","features.messages.impl.forward_ForwardMessagesView_Night_1_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_2_en","features.messages.impl.forward_ForwardMessagesView_Night_2_en",0,], -["features.messages.impl.forward_ForwardMessagesView_Day_3_en","features.messages.impl.forward_ForwardMessagesView_Night_3_en",20360,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20360,], +["features.messages.impl.forward_ForwardMessagesView_Day_3_en","features.messages.impl.forward_ForwardMessagesView_Night_3_en",20364,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20364,], ["libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Night_0_en",0,], ["libraries.designsystem.components.button_GradientFloatingActionButton_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButton_Night_0_en",0,], ["features.messages.impl.timeline.components.group_GroupHeaderView_Day_0_en","features.messages.impl.timeline.components.group_GroupHeaderView_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPage_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPage_Night_0_en",0,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20360,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20360,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20364,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20364,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20360,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20360,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20364,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20364,], ["features.home.impl_HomeView_Day_11_en","features.home.impl_HomeView_Night_11_en",0,], ["features.home.impl_HomeView_Day_12_en","features.home.impl_HomeView_Night_12_en",0,], -["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20360,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20360,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20360,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20360,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20360,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20360,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20360,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20360,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20360,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20360,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20360,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20360,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20364,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20364,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20364,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20364,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20364,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20364,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20364,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20364,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20364,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20364,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20364,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20364,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -496,8 +498,8 @@ export const screenshots = [ ["libraries.designsystem.icons_IconsCompound_Day_5_en","libraries.designsystem.icons_IconsCompound_Night_5_en",0,], ["libraries.designsystem.icons_IconsOther_Day_0_en","libraries.designsystem.icons_IconsOther_Night_0_en",0,], ["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_0_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_0_en",0,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20360,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20360,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20364,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20364,], ["libraries.mediaviewer.impl.gallery.ui_ImageItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_ImageItemView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en",0,], @@ -505,106 +507,108 @@ export const screenshots = [ ["libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20360,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20364,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20360,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20364,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en",0,], -["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20360,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20360,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20364,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20364,], ["features.networkmonitor.api.ui_Indicator_Day_0_en","features.networkmonitor.api.ui_Indicator_Night_0_en",0,], ["libraries.designsystem.atomic.molecules_InfoListItemMolecule_Day_0_en","libraries.designsystem.atomic.molecules_InfoListItemMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.organisms_InfoListOrganism_Day_0_en","libraries.designsystem.atomic.organisms_InfoListOrganism_Night_0_en",0,], ["libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Day_0_en","libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Night_0_en",0,], -["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20360,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20360,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20360,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20364,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20364,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20364,], ["features.invitepeople.impl_InvitePeopleView_Day_2_en","features.invitepeople.impl_InvitePeopleView_Night_2_en",0,], ["features.invitepeople.impl_InvitePeopleView_Day_3_en","features.invitepeople.impl_InvitePeopleView_Night_3_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20360,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20360,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20360,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20360,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20364,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20364,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20364,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20364,], ["features.invitepeople.impl_InvitePeopleView_Day_8_en","features.invitepeople.impl_InvitePeopleView_Night_8_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20360,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20360,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20360,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20364,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20364,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20364,], ["features.joinroom.impl_JoinRoomView_Day_0_en","features.joinroom.impl_JoinRoomView_Night_0_en",0,], -["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20360,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20360,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20360,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20360,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20364,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20364,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20364,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20364,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], ["features.leaveroom.impl_LeaveRoomView_Day_0_en","features.leaveroom.impl_LeaveRoomView_Night_0_en",0,], -["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20360,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20360,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20360,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20364,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20364,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20367,], ["libraries.designsystem.background_LightGradientBackground_Day_0_en","libraries.designsystem.background_LightGradientBackground_Night_0_en",0,], ["libraries.designsystem.theme.components_LinearProgressIndicator_Progress_Indicators_en","",0,], ["features.messages.impl.link_LinkView_Day_0_en","features.messages.impl.link_LinkView_Night_0_en",0,], -["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20360,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20364,], ["libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ListDialog_Day_0_en","libraries.designsystem.components.dialogs_ListDialog_Night_0_en",0,], ["libraries.designsystem.theme.components_ListItemPrimaryActionWithIcon_List_item_-_Primary_action_&_Icon_List_items_en","",0,], @@ -659,37 +663,37 @@ export const screenshots = [ ["libraries.designsystem.theme.components_ListSupportingTextSmallPadding_List_supporting_text_-_small_padding_List_sections_en","",0,], ["libraries.textcomposer.components_LiveWaveformView_Day_0_en","libraries.textcomposer.components_LiveWaveformView_Night_0_en",0,], ["appnav.room.joined_LoadingRoomNodeView_Day_0_en","appnav.room.joined_LoadingRoomNodeView_Night_0_en",0,], -["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20360,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20360,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20360,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20360,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20364,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20364,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20364,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20364,], ["appnav.loggedin_LoggedInView_Day_0_en","appnav.loggedin_LoggedInView_Night_0_en",0,], -["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20360,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20360,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20360,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20360,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20360,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20360,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20360,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20360,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20360,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20360,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20360,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20360,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20360,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20360,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20360,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20360,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20360,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20360,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20360,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20360,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20360,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20360,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20360,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20360,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20364,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20364,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20364,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20364,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20364,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20364,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20364,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20364,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20364,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20364,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20364,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20364,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20364,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20364,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20364,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20364,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20364,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20364,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20364,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20364,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20364,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20364,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20364,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20364,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20360,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20364,], ["libraries.textcomposer.components.markdown_MarkdownTextInput_Day_0_en","libraries.textcomposer.components.markdown_MarkdownTextInput_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Night_0_en",0,], @@ -702,22 +706,22 @@ export const screenshots = [ ["libraries.matrix.ui.components_MatrixUserRow_Day_1_en","libraries.matrix.ui.components_MatrixUserRow_Night_1_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_0_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_1_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_1_en",0,], -["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20360,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20360,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20364,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20364,], ["libraries.mediaviewer.impl.local.file_MediaFileView_Day_0_en","libraries.mediaviewer.impl.local.file_MediaFileView_Night_0_en",0,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20360,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20360,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20364,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20364,], ["libraries.mediaviewer.impl.local.image_MediaImageView_Day_0_en","libraries.mediaviewer.impl.local.image_MediaImageView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_0_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_1_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_1_en",0,], @@ -725,14 +729,14 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.video_MediaVideoView_Day_0_en","libraries.mediaviewer.impl.local.video_MediaVideoView_Night_0_en",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_0_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_10_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20360,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20360,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20364,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20364,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20360,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20364,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_15_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_16_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_1_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20360,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20364,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -746,7 +750,7 @@ export const screenshots = [ ["libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en","libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en",0,], ["libraries.designsystem.theme.components.previews_Menu_Menus_en","",0,], ["features.messages.impl.messagecomposer_MessageComposerViewVoice_Day_0_en","features.messages.impl.messagecomposer_MessageComposerViewVoice_Night_0_en",0,], -["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20360,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20364,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_0_en","features.messages.impl.timeline.components_MessageEventBubble_Night_0_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_1_en","features.messages.impl.timeline.components_MessageEventBubble_Night_1_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_2_en","features.messages.impl.timeline.components_MessageEventBubble_Night_2_en",0,], @@ -755,7 +759,7 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessageEventBubble_Day_5_en","features.messages.impl.timeline.components_MessageEventBubble_Night_5_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_6_en","features.messages.impl.timeline.components_MessageEventBubble_Night_6_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_7_en","features.messages.impl.timeline.components_MessageEventBubble_Night_7_en",0,], -["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20360,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20364,], ["features.messages.impl.timeline.components_MessageStateEventContainer_Day_0_en","features.messages.impl.timeline.components_MessageStateEventContainer_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonAdd_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonAdd_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonExtra_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonExtra_Night_0_en",0,], @@ -763,137 +767,137 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20360,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20360,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20360,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20360,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20360,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20360,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20360,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20360,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20360,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20360,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20360,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20360,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20360,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20360,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20360,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20364,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20364,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20364,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20364,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20364,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20364,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20364,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20364,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20364,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20364,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20364,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20364,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20364,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20364,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20364,], ["features.migration.impl_MigrationView_Day_0_en","features.migration.impl_MigrationView_Night_0_en",0,], -["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20360,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20364,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20360,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20364,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20360,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20360,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20360,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20364,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20364,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20364,], ["libraries.designsystem.atomic.pages_OnBoardingPage_Day_0_en","libraries.designsystem.atomic.pages_OnBoardingPage_Night_0_en",0,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20360,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20360,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20364,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20364,], ["libraries.designsystem.background_OnboardingBackground_Day_0_en","libraries.designsystem.background_OnboardingBackground_Night_0_en",0,], -["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20360,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20364,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_12_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_12_en",0,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_13_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_13_en",0,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20360,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20360,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20364,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20364,], ["libraries.designsystem.theme.components_OutlinedButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonSmall_Buttons_en","",0,], -["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20360,], -["features.changeroommemberroles.impl_PendingMemberRowWithLongName_Day_0_en","features.changeroommemberroles.impl_PendingMemberRowWithLongName_Night_0_en",20360,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20360,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20360,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20360,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20360,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20364,], +["features.changeroommemberroles.impl_PendingMemberRowWithLongName_Day_0_en","features.changeroommemberroles.impl_PendingMemberRowWithLongName_Night_0_en",20364,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20364,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20364,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20364,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20364,], ["features.lockscreen.impl.components_PinEntryTextField_Day_0_en","features.lockscreen.impl.components_PinEntryTextField_Night_0_en",0,], ["libraries.designsystem.components_PinIcon_Day_0_en","libraries.designsystem.components_PinIcon_Night_0_en",0,], ["features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en","features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en",0,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20360,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20360,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20364,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20364,], ["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_0_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_0_en",0,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20360,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20360,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20360,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20360,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20360,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20360,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20364,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20364,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20364,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20364,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20364,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20364,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20360,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20360,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20360,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20360,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20360,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20364,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20364,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20364,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20364,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20364,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Night_0_en",0,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Night_0_en",0,], -["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20360,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20360,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20360,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20360,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20360,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20360,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20360,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20360,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20360,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20360,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20360,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20364,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20364,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20364,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20364,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20364,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20364,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20364,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20364,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20364,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20364,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20364,], ["features.poll.api.pollcontent_PollTitleView_Day_0_en","features.poll.api.pollcontent_PollTitleView_Night_0_en",0,], ["libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en","",0,], @@ -907,207 +911,207 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20360,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20360,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20360,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20360,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20364,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20364,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20364,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20364,], ["features.messages.impl.timeline.components.event_ProgressButton_Day_0_en","features.messages.impl.timeline.components.event_ProgressButton_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20360,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20360,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20364,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20364,], ["libraries.designsystem.components_ProgressDialogWithTextAndContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithTextAndContent_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20360,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20360,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20360,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20360,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20360,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20360,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20360,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20360,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20360,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20360,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20360,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20360,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20360,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20360,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20360,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20360,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20364,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20364,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20364,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20364,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20364,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20364,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20364,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20364,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20364,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20364,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20364,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20364,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20364,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20364,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20364,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20364,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20360,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20360,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20364,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20364,], ["features.rageshake.api.preferences_RageshakePreferencesView_Day_1_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_1_en",0,], ["features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Day_0_en","features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Night_0_en",0,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20360,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20360,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20360,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20360,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20360,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20360,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20360,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20364,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20364,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20364,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20364,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20364,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20364,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20364,], ["libraries.designsystem.atomic.atoms_RedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_RedIndicatorAtom_Night_0_en",0,], ["features.messages.impl.timeline.components_ReplySwipeIndicator_Day_0_en","features.messages.impl.timeline.components_ReplySwipeIndicator_Night_0_en",0,], -["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20360,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20360,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20360,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20360,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20360,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20360,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20360,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20360,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20360,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20360,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20360,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20360,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20360,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20360,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20360,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20360,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20360,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20364,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20364,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20364,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20364,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20364,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20364,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20364,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20364,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20364,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20364,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20364,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20364,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20364,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20364,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20364,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20364,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20364,], ["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_0_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_0_en",0,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20360,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20360,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20360,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_0_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_1_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_2_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_3_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_4_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_5_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_6_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_7_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_7_en",20360,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_8_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_8_en",20360,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20364,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20364,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20364,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_0_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_1_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_2_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_3_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_4_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_5_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_6_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_7_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_7_en",20364,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_8_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_8_en",20364,], ["libraries.matrix.ui.room.address_RoomAddressField_Day_0_en","libraries.matrix.ui.room.address_RoomAddressField_Night_0_en",0,], ["features.roomaliasresolver.impl_RoomAliasResolverView_Day_0_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_0_en",0,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20360,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20360,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20360,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20360,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20360,], -["features.roomdetails.impl_RoomDetails_0_en","",20360,], -["features.roomdetails.impl_RoomDetails_10_en","",20360,], -["features.roomdetails.impl_RoomDetails_11_en","",20360,], -["features.roomdetails.impl_RoomDetails_12_en","",20360,], -["features.roomdetails.impl_RoomDetails_13_en","",20360,], -["features.roomdetails.impl_RoomDetails_14_en","",20360,], -["features.roomdetails.impl_RoomDetails_15_en","",20360,], -["features.roomdetails.impl_RoomDetails_16_en","",20360,], -["features.roomdetails.impl_RoomDetails_17_en","",20360,], -["features.roomdetails.impl_RoomDetails_18_en","",20360,], -["features.roomdetails.impl_RoomDetails_19_en","",20360,], -["features.roomdetails.impl_RoomDetails_1_en","",20360,], -["features.roomdetails.impl_RoomDetails_2_en","",20360,], -["features.roomdetails.impl_RoomDetails_3_en","",20360,], -["features.roomdetails.impl_RoomDetails_4_en","",20360,], -["features.roomdetails.impl_RoomDetails_5_en","",20360,], -["features.roomdetails.impl_RoomDetails_6_en","",20360,], -["features.roomdetails.impl_RoomDetails_7_en","",20360,], -["features.roomdetails.impl_RoomDetails_8_en","",20360,], -["features.roomdetails.impl_RoomDetails_9_en","",20360,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20360,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20360,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20360,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20360,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20360,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20360,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20360,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20360,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20360,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20364,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20364,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20364,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20364,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20364,], +["features.roomdetails.impl_RoomDetails_0_en","",20364,], +["features.roomdetails.impl_RoomDetails_10_en","",20364,], +["features.roomdetails.impl_RoomDetails_11_en","",20364,], +["features.roomdetails.impl_RoomDetails_12_en","",20364,], +["features.roomdetails.impl_RoomDetails_13_en","",20364,], +["features.roomdetails.impl_RoomDetails_14_en","",20364,], +["features.roomdetails.impl_RoomDetails_15_en","",20364,], +["features.roomdetails.impl_RoomDetails_16_en","",20364,], +["features.roomdetails.impl_RoomDetails_17_en","",20364,], +["features.roomdetails.impl_RoomDetails_18_en","",20364,], +["features.roomdetails.impl_RoomDetails_19_en","",20364,], +["features.roomdetails.impl_RoomDetails_1_en","",20364,], +["features.roomdetails.impl_RoomDetails_2_en","",20364,], +["features.roomdetails.impl_RoomDetails_3_en","",20364,], +["features.roomdetails.impl_RoomDetails_4_en","",20364,], +["features.roomdetails.impl_RoomDetails_5_en","",20364,], +["features.roomdetails.impl_RoomDetails_6_en","",20364,], +["features.roomdetails.impl_RoomDetails_7_en","",20364,], +["features.roomdetails.impl_RoomDetails_8_en","",20364,], +["features.roomdetails.impl_RoomDetails_9_en","",20364,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20364,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20364,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20364,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20364,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20364,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20364,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20364,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20364,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20364,], ["features.home.impl.components_RoomListContentView_Day_2_en","features.home.impl.components_RoomListContentView_Night_2_en",0,], -["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20360,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20360,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20360,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20360,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20360,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20360,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20360,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20360,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20364,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20364,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20364,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20364,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20364,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20364,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20364,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20364,], ["features.home.impl.search_RoomListSearchContent_Day_0_en","features.home.impl.search_RoomListSearchContent_Night_0_en",0,], -["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20360,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20360,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20360,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20360,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20364,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20364,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20364,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20364,], ["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",0,], -["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20360,], -["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20360,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20360,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20360,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20360,], +["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20364,], +["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20364,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20364,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20364,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20364,], ["features.home.impl.components_RoomSummaryPlaceholderRow_Day_0_en","features.home.impl.components_RoomSummaryPlaceholderRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_0_en","features.home.impl.components_RoomSummaryRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_10_en","features.home.impl.components_RoomSummaryRow_Night_10_en",0,], @@ -1130,13 +1134,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20360,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20360,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20364,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20367,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_4_en","features.home.impl.components_RoomSummaryRow_Night_4_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_5_en","features.home.impl.components_RoomSummaryRow_Night_5_en",0,], @@ -1144,80 +1149,80 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_7_en","features.home.impl.components_RoomSummaryRow_Night_7_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_8_en","features.home.impl.components_RoomSummaryRow_Night_8_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_9_en","features.home.impl.components_RoomSummaryRow_Night_9_en",0,], -["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20360,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20360,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20360,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20364,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20364,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20364,], ["appicon.enterprise_RoundIcon_en","",0,], ["appicon.element_RoundIcon_en","",0,], ["libraries.designsystem.atomic.atoms_RoundedIconAtom_Day_0_en","libraries.designsystem.atomic.atoms_RoundedIconAtom_Night_0_en",0,], -["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20360,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20360,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20360,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20364,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20364,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20364,], ["libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en","",0,], -["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20360,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20364,], ["libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarInactive_Search_views_en","",0,], -["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20360,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20360,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20360,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20360,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20360,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20360,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20360,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20360,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20360,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20360,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20360,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20360,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20360,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20360,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20364,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20364,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20364,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20364,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20364,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20364,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20364,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20364,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20364,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20364,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20364,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20364,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20364,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20364,], ["libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_0_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_1_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_1_en",0,], @@ -1231,11 +1236,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20360,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20360,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20360,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20360,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20360,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20364,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20364,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20364,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20364,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20364,], ["libraries.matrix.ui.messages.sender_SenderName_Day_0_en","libraries.matrix.ui.messages.sender_SenderName_Night_0_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_1_en","libraries.matrix.ui.messages.sender_SenderName_Night_1_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_2_en","libraries.matrix.ui.messages.sender_SenderName_Night_2_en",0,], @@ -1245,27 +1250,27 @@ export const screenshots = [ ["libraries.matrix.ui.messages.sender_SenderName_Day_6_en","libraries.matrix.ui.messages.sender_SenderName_Night_6_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_7_en","libraries.matrix.ui.messages.sender_SenderName_Night_7_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_8_en","libraries.matrix.ui.messages.sender_SenderName_Night_8_en",0,], -["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20360,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20360,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20360,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20360,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20360,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20360,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20360,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20360,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20364,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20364,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20364,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20364,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20364,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20364,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20364,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20364,], ["features.share.impl_ShareView_Day_0_en","features.share.impl_ShareView_Night_0_en",0,], ["features.share.impl_ShareView_Day_1_en","features.share.impl_ShareView_Night_1_en",0,], ["features.share.impl_ShareView_Day_2_en","features.share.impl_ShareView_Night_2_en",0,], -["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20360,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20360,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20360,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20360,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20360,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20360,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20360,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20360,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20360,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20360,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20364,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20364,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20364,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20364,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20364,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20364,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20364,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20364,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20364,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20364,], ["libraries.designsystem.components.dialogs_SingleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_SingleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_SingleSelectionListItemCustomFormattert_Single_selection_List_item_-_custom_formatter_List_items_en","",0,], @@ -1274,86 +1279,95 @@ export const screenshots = [ ["libraries.designsystem.components.list_SingleSelectionListItemUnselectedWithSupportingText_Single_selection_List_item_-_no_selection,_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_SingleSelectionListItem_Single_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_Sliders_Sliders_en","",0,], -["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20360,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20364,], ["libraries.designsystem.theme.components_SnackbarWithActionAndCloseButton_Snackbar_with_action_and_close_button_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLineAndCloseButton_Snackbar_with_action_and_close_button_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLine_Snackbar_with_action_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithAction_Snackbar_with_action_Snackbars_en","",0,], ["libraries.designsystem.theme.components_Snackbar_Snackbar_Snackbars_en","",0,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20367,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20360,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20360,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20360,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20364,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20364,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20364,], ["libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Day_0_en","libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Night_0_en",0,], ["libraries.matrix.ui.components_SpaceMembersView_Day_0_en","libraries.matrix.ui.components_SpaceMembersView_Night_0_en",0,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20367,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20367,], ["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",0,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20360,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20360,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20360,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20364,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20364,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20364,], ["libraries.designsystem.modifiers_SquareSizeModifierInsideSquare_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeHeight_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeWidth_en","",0,], -["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20360,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20360,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20360,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20360,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20360,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20360,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20360,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20364,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20364,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20364,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20364,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20364,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20364,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20364,], ["features.location.api_StaticMapView_Day_0_en","features.location.api_StaticMapView_Night_0_en",0,], -["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20360,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20364,], ["libraries.designsystem.atomic.pages_SunsetPage_Day_0_en","libraries.designsystem.atomic.pages_SunsetPage_Night_0_en",0,], ["libraries.designsystem.components.button_SuperButton_Day_0_en","libraries.designsystem.components.button_SuperButton_Night_0_en",0,], ["libraries.designsystem.theme.components_Surface_en","",0,], ["libraries.designsystem.theme.components_Switch_Toggles_en","",0,], -["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20360,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20364,], ["libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TextButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonSmall_Buttons_en","",0,], -["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20360,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20360,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20360,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20360,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20360,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20360,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20360,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20360,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20360,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20360,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20360,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20360,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20360,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20360,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20360,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20364,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20364,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20364,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20364,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20364,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20364,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20364,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20364,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20364,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20364,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20364,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20364,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20364,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20364,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20364,], ["libraries.textcomposer_TextComposerVoice_Day_0_en","libraries.textcomposer_TextComposerVoice_Night_0_en",0,], ["libraries.designsystem.theme.components_TextDark_Text_en","",0,], -["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20360,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20360,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20364,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20364,], ["libraries.designsystem.components.list_TextFieldListItemEmpty_Text_field_List_item_-_empty_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItemTextFieldValue_Text_field_List_item_-_textfieldvalue_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItem_Text_field_List_item_-_text_List_items_en","",0,], @@ -1365,16 +1379,16 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.txt_TextFileContentView_Day_3_en","libraries.mediaviewer.impl.local.txt_TextFileContentView_Night_3_en",0,], ["libraries.textcomposer.components_TextFormatting_Day_0_en","libraries.textcomposer.components_TextFormatting_Night_0_en",0,], ["libraries.designsystem.theme.components_TextLight_Text_en","",0,], -["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20360,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20360,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20360,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20360,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20360,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20364,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20364,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20364,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20364,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20364,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_0_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_1_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_2_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20360,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20360,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20364,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20364,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_5_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_6_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_7_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_7_en",0,], @@ -1384,18 +1398,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20360,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20364,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_0_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_1_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20360,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowLongSenderName_en","",0,], @@ -1403,18 +1417,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20360,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20364,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_6_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20360,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20360,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20364,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20364,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20360,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20364,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en",0,], @@ -1423,41 +1437,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20360,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20364,], ["features.messages.impl.timeline.components_TimelineItemEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRow_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20360,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20364,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20360,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20360,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20364,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20364,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemInformativeView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemInformativeView_Night_0_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20360,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20364,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20360,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20360,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20364,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20364,], ["features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20360,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20360,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20364,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20364,], ["features.messages.impl.timeline.components_TimelineItemReactionsView_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsView_Night_0_en",0,], -["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20360,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20364,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_0_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_0_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_1_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_1_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_2_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_2_en",0,], @@ -1466,8 +1480,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_5_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_5_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_6_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_6_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_7_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_7_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20360,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20360,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20364,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20364,], ["features.messages.impl.timeline.components_TimelineItemStateEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemStateEventRow_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStateView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStateView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStickerView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStickerView_Night_0_en",0,], @@ -1482,8 +1496,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_4_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_5_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20360,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20360,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20364,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20364,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_2_en",0,], @@ -1506,85 +1520,85 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en","features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Day_0_en","features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Night_0_en",0,], -["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20360,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20364,], ["features.messages.impl.timeline_TimelineView_Day_10_en","features.messages.impl.timeline_TimelineView_Night_10_en",0,], -["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20360,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20360,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20364,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20364,], ["features.messages.impl.timeline_TimelineView_Day_2_en","features.messages.impl.timeline_TimelineView_Night_2_en",0,], ["features.messages.impl.timeline_TimelineView_Day_3_en","features.messages.impl.timeline_TimelineView_Night_3_en",0,], -["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20360,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20364,], ["features.messages.impl.timeline_TimelineView_Day_5_en","features.messages.impl.timeline_TimelineView_Night_5_en",0,], -["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20360,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20364,], ["features.messages.impl.timeline_TimelineView_Day_7_en","features.messages.impl.timeline_TimelineView_Night_7_en",0,], -["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20360,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20364,], ["features.messages.impl.timeline_TimelineView_Day_9_en","features.messages.impl.timeline_TimelineView_Night_9_en",0,], ["libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TopAppBarStr_App_Bars_en","",0,], ["libraries.designsystem.theme.components_TopAppBar_App_Bars_en","",0,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20360,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20360,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20364,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20364,], ["features.messages.impl.typing_TypingNotificationView_Day_0_en","features.messages.impl.typing_TypingNotificationView_Night_0_en",0,], -["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20360,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20360,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20360,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20360,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20360,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20360,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20364,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20364,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20364,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20364,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20364,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20364,], ["features.messages.impl.typing_TypingNotificationView_Day_7_en","features.messages.impl.typing_TypingNotificationView_Night_7_en",0,], ["features.messages.impl.typing_TypingNotificationView_Day_8_en","features.messages.impl.typing_TypingNotificationView_Night_8_en",0,], ["libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Night_0_en",0,], -["libraries.matrix.ui.components_UnresolvedUserRow_en","",20360,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20364,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20360,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20360,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20360,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20360,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20364,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20364,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20364,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20364,], ["features.startchat.impl.components_UserListView_Day_3_en","features.startchat.impl.components_UserListView_Night_3_en",0,], ["features.startchat.impl.components_UserListView_Day_4_en","features.startchat.impl.components_UserListView_Night_4_en",0,], ["features.startchat.impl.components_UserListView_Day_5_en","features.startchat.impl.components_UserListView_Night_5_en",0,], ["features.startchat.impl.components_UserListView_Day_6_en","features.startchat.impl.components_UserListView_Night_6_en",0,], -["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20360,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20364,], ["features.startchat.impl.components_UserListView_Day_8_en","features.startchat.impl.components_UserListView_Night_8_en",0,], -["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20360,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20364,], ["features.preferences.impl.user_UserPreferences_Day_0_en","features.preferences.impl.user_UserPreferences_Night_0_en",0,], ["features.preferences.impl.user_UserPreferences_Day_1_en","features.preferences.impl.user_UserPreferences_Night_1_en",0,], ["features.preferences.impl.user_UserPreferences_Day_2_en","features.preferences.impl.user_UserPreferences_Night_2_en",0,], -["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20360,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20360,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20360,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20360,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20360,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20360,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20360,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20360,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20360,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20360,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20360,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20360,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20364,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20364,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20364,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20364,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20364,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20364,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20364,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20364,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20364,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20364,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20364,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20364,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20360,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20360,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20364,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20364,], ["features.viewfolder.impl.file_ViewFileView_Day_0_en","features.viewfolder.impl.file_ViewFileView_Night_0_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_1_en","features.viewfolder.impl.file_ViewFileView_Night_1_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_2_en","features.viewfolder.impl.file_ViewFileView_Night_2_en",0,], -["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20360,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20364,], ["features.viewfolder.impl.file_ViewFileView_Day_4_en","features.viewfolder.impl.file_ViewFileView_Night_4_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_5_en","features.viewfolder.impl.file_ViewFileView_Night_5_en",0,], ["features.viewfolder.impl.folder_ViewFolderView_Day_0_en","features.viewfolder.impl.folder_ViewFolderView_Night_0_en",0,], From d2e5b43674e2e8589084a3e395943e6698487d98 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 6 Oct 2025 06:40:52 -0400 Subject: [PATCH 50/73] Only offer to verify if a cross-signed device is available (#5433) * Only offer to verify if a cross-signed device is available * Fix tests * use the right exception mapper * adjust flag name and logic in ChooseSelfVerificationState * add comment * switch order of states to match previous logic --- .../ChooseSelfVerificationModePresenter.kt | 4 ++-- .../ChooseSelfVerificationModeState.kt | 2 +- ...ChooseSelfVerificationModeStateProvider.kt | 12 +++++----- .../ChooseSelfVerificationModeView.kt | 2 +- ...oseSessionVerificationModePresenterTest.kt | 6 ++--- .../ChooseSessionVerificationModeViewTest.kt | 2 +- .../api/encryption/EncryptionService.kt | 1 + .../impl/encryption/RustEncryptionService.kt | 23 +++++++++++++++++++ .../impl/fixtures/fakes/FakeFfiEncryption.kt | 4 ++++ .../test/encryption/FakeEncryptionService.kt | 5 ++++ 10 files changed, 47 insertions(+), 14 deletions(-) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt index e278e803c4..eb3c1330b3 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt @@ -26,7 +26,7 @@ class ChooseSelfVerificationModePresenter( ) : Presenter { @Composable override fun present(): ChooseSelfVerificationModeState { - val isLastDevice by encryptionService.isLastDevice.collectAsState() + val hasDevicesToVerifyAgainst by encryptionService.hasDevicesToVerifyAgainst.collectAsState() val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState() val canEnterRecoveryKey by remember { derivedStateOf { recoveryState == RecoveryState.INCOMPLETE } } @@ -39,7 +39,7 @@ class ChooseSelfVerificationModePresenter( } return ChooseSelfVerificationModeState( - isLastDevice = isLastDevice, + canUseAnotherDevice = hasDevicesToVerifyAgainst, canEnterRecoveryKey = canEnterRecoveryKey, directLogoutState = directLogoutState, eventSink = ::eventHandler, diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeState.kt index 21c37a4ae2..117768a6d2 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeState.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeState.kt @@ -10,7 +10,7 @@ package io.element.android.features.ftue.impl.sessionverification.choosemode import io.element.android.features.logout.api.direct.DirectLogoutState data class ChooseSelfVerificationModeState( - val isLastDevice: Boolean, + val canUseAnotherDevice: Boolean, val canEnterRecoveryKey: Boolean, val directLogoutState: DirectLogoutState, val eventSink: (ChooseSelfVerificationModeEvent) -> Unit, diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeStateProvider.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeStateProvider.kt index 574aa367c6..e053728e2c 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeStateProvider.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeStateProvider.kt @@ -13,18 +13,18 @@ import io.element.android.features.logout.api.direct.aDirectLogoutState class ChooseSelfVerificationModeStateProvider : PreviewParameterProvider { override val values = sequenceOf( - aChooseSelfVerificationModeState(isLastDevice = true, canEnterRecoveryKey = true), - aChooseSelfVerificationModeState(isLastDevice = true, canEnterRecoveryKey = false), - aChooseSelfVerificationModeState(isLastDevice = false, canEnterRecoveryKey = true), - aChooseSelfVerificationModeState(isLastDevice = false, canEnterRecoveryKey = false), + aChooseSelfVerificationModeState(canUseAnotherDevice = false, canEnterRecoveryKey = true), + aChooseSelfVerificationModeState(canUseAnotherDevice = false, canEnterRecoveryKey = false), + aChooseSelfVerificationModeState(canUseAnotherDevice = true, canEnterRecoveryKey = true), + aChooseSelfVerificationModeState(canUseAnotherDevice = true, canEnterRecoveryKey = false), ) } fun aChooseSelfVerificationModeState( - isLastDevice: Boolean = false, + canUseAnotherDevice: Boolean = true, canEnterRecoveryKey: Boolean = true, ) = ChooseSelfVerificationModeState( - isLastDevice = isLastDevice, + canUseAnotherDevice = canUseAnotherDevice, canEnterRecoveryKey = canEnterRecoveryKey, directLogoutState = aDirectLogoutState(), eventSink = {}, diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt index 74eed0115c..b07c04ac9c 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt @@ -76,7 +76,7 @@ fun ChooseSelfVerificationModeView( ButtonColumnMolecule( modifier = Modifier.padding(bottom = 16.dp) ) { - if (state.isLastDevice.not()) { + if (state.canUseAnotherDevice) { Button( modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.screen_identity_use_another_device), diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt index 3801001ed4..3dbf5a6932 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt @@ -24,15 +24,15 @@ class ChooseSessionVerificationModePresenterTest { @Test fun `initial state - is relayed from EncryptionService`() = runTest { val encryptionService = FakeEncryptionService().apply { - // Is last device - emitIsLastDevice(true) + // Has device to verify against + emitHasDevicesToVerifyAgainst(false) // Can enter recovery key emitRecoveryState(RecoveryState.INCOMPLETE) } val presenter = createPresenter(encryptionService = encryptionService) presenter.test { awaitItem().run { - assertThat(isLastDevice).isTrue() + assertThat(canUseAnotherDevice).isFalse() assertThat(canEnterRecoveryKey).isTrue() assertThat(directLogoutState.logoutAction.isUninitialized()).isTrue() } diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModeViewTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModeViewTest.kt index b89e3e42bd..ed7d99dd19 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModeViewTest.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModeViewTest.kt @@ -43,7 +43,7 @@ class ChooseSessionVerificationModeViewTest { fun `clicking on use another device calls the callback`() { ensureCalledOnce { callback -> rule.setChooseSelfVerificationModeView( - aChooseSelfVerificationModeState(isLastDevice = false), + aChooseSelfVerificationModeState(canUseAnotherDevice = true), onUseAnotherDevice = callback, ) rule.clickOn(R.string.screen_identity_use_another_device) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt index 1635cce375..961178ee3e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt @@ -17,6 +17,7 @@ interface EncryptionService { val recoveryStateStateFlow: StateFlow val enableRecoveryProgressStateFlow: StateFlow val isLastDevice: StateFlow + val hasDevicesToVerifyAgainst: StateFlow suspend fun enableBackups(): Result diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt index 7c87666fe7..977663c883 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.sync.SyncState +import io.element.android.libraries.matrix.impl.exception.mapClientException import io.element.android.libraries.matrix.impl.sync.RustSyncService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose @@ -96,6 +97,20 @@ internal class RustEncryptionService( } .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false) + /** + * Check if the user has any devices available to verify against every 5 seconds. + * TODO This is a temporary workaround, when we will have a way to observe + * the sessions, this code will have to be updated. + */ + override val hasDevicesToVerifyAgainst: StateFlow = flow { + while (currentCoroutineContext().isActive) { + val result = hasDevicesToVerifyAgainst().getOrDefault(false) + emit(result) + delay(5_000) + } + } + .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false) + override suspend fun enableBackups(): Result = withContext(dispatchers.io) { runCatchingExceptions { service.enableBackups() @@ -171,6 +186,14 @@ internal class RustEncryptionService( } } + private suspend fun hasDevicesToVerifyAgainst(): Result = withContext(dispatchers.io) { + runCatchingExceptions { + service.hasDevicesToVerifyAgainst() + }.mapFailure { + it.mapClientException() + } + } + override suspend fun resetRecoveryKey(): Result = withContext(dispatchers.io) { runCatchingExceptions { service.resetRecoveryKey() diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiEncryption.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiEncryption.kt index 536288caef..177ab5b251 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiEncryption.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiEncryption.kt @@ -32,6 +32,10 @@ class FakeFfiEncryption : Encryption(NoPointer) { return false } + override suspend fun hasDevicesToVerifyAgainst(): Boolean { + return true + } + override fun backupState(): BackupState { return BackupState.ENABLED } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt index 7226465772..b4199ff8e4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt @@ -34,6 +34,7 @@ class FakeEncryptionService( override val recoveryStateStateFlow: MutableStateFlow = MutableStateFlow(RecoveryState.UNKNOWN) override val enableRecoveryProgressStateFlow: MutableStateFlow = MutableStateFlow(EnableRecoveryProgress.Starting) override val isLastDevice: MutableStateFlow = MutableStateFlow(false) + override val hasDevicesToVerifyAgainst: MutableStateFlow = MutableStateFlow(true) private var waitForBackupUploadSteadyStateFlow: Flow = flowOf() private var recoverFailure: Exception? = null @@ -83,6 +84,10 @@ class FakeEncryptionService( this.isLastDevice.value = isLastDevice } + fun emitHasDevicesToVerifyAgainst(hasDevicesToVerifyAgainst: Boolean) { + this.hasDevicesToVerifyAgainst.value = hasDevicesToVerifyAgainst + } + override suspend fun resetRecoveryKey(): Result = simulateLongTask { return Result.success(FAKE_RECOVERY_KEY) } From 3080baace2cceb2809893af20b99b5d01954aa8e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 12:52:59 +0200 Subject: [PATCH 51/73] Fix tests. --- .../android/features/home/impl/HomePresenterTest.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt index 8048564e2b..938e0720d7 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt @@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore @@ -52,6 +53,8 @@ class HomePresenterTest { @get:Rule val warmUpRule = WarmUpRule() + private val isSpaceEnabled = FeatureFlags.Space.defaultValue(aBuildMeta()) + @Test fun `present - should start with no user and then load user with success`() = runTest { val matrixClient = FakeMatrixClient( @@ -75,6 +78,7 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { + if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo( MatrixUser(A_USER_ID, null, null) @@ -86,8 +90,8 @@ class HomePresenterTest { MatrixUser(A_USER_ID, A_USER_NAME, AN_AVATAR_URL) ) assertThat(withUserState.showAvatarIndicator).isFalse() - assertThat(withUserState.isSpaceFeatureEnabled).isFalse() - assertThat(withUserState.showNavigationBar).isFalse() + assertThat(withUserState.isSpaceFeatureEnabled).isEqualTo(isSpaceEnabled) + assertThat(withUserState.showNavigationBar).isEqualTo(isSpaceEnabled) } } @@ -138,6 +142,7 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { + if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.showAvatarIndicator).isFalse() indicatorService.setShowRoomListTopBarIndicator(true) @@ -162,6 +167,7 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { + if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(MatrixUser(matrixClient.sessionId)) // No new state is coming @@ -182,6 +188,7 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { + if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats) initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) From de8dc6b8362072c4e506ef04fcc366c97baa5716 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:08:39 +0000 Subject: [PATCH 52/73] fix(deps): update dependency com.posthog:posthog-android to v3.23.0 (#5463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f837a1e55b..0c6e2e85e7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -205,7 +205,7 @@ haze = { module = "dev.chrisbanes.haze:haze", version.ref = "haze" } haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = "haze" } # Analytics -posthog = "com.posthog:posthog-android:3.22.0" +posthog = "com.posthog:posthog-android:3.23.0" sentry = "io.sentry:sentry-android:8.23.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.28.0" From be9b2b006649f6c55eacdbfcd76563c73dc99e61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:15:50 +0200 Subject: [PATCH 53/73] fix(deps): update roborazzi to v1.50.0 (#5464) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0c6e2e85e7..3d9f799002 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.46.1" +roborazzi = "1.50.0" # Jetbrain datetime = "0.7.1" From 8d94df09ac430d31bfdc1a3f99f39d011bfb145e Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 6 Oct 2025 14:21:01 +0200 Subject: [PATCH 54/73] feature(space): compute space room name locally --- .../home/impl/spaces/SpaceRoomProvider.kt | 4 ++-- .../impl/leave/LeaveSpaceStateProvider.kt | 2 +- .../space/impl/root/SpaceStateProvider.kt | 2 +- .../libraries/matrix/api/spaces/SpaceRoom.kt | 14 ++++++++++++- .../matrix/impl/spaces/SpaceRoomMapper.kt | 3 ++- .../matrix/ui/components/SpaceRoomProvider.kt | 20 +++++++++++++------ .../previewutils/room/SpaceRoomFixture.kt | 6 ++++-- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/SpaceRoomProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/SpaceRoomProvider.kt index 474e08293a..56d441a42e 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/SpaceRoomProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/SpaceRoomProvider.kt @@ -30,7 +30,7 @@ class SpaceRoomProvider : PreviewParameterProvider { roomId = RoomId("!spaceId1:example.com"), ), aSpaceRoom( - name = null, + rawName = null, numJoinedMembers = 5, childrenCount = 10, worldReadable = true, @@ -39,7 +39,7 @@ class SpaceRoomProvider : PreviewParameterProvider { state = CurrentUserMembership.INVITED, ), aSpaceRoom( - name = null, + rawName = null, numJoinedMembers = 5, childrenCount = 10, worldReadable = true, diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt index 16eb85442c..85518f8b18 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceStateProvider.kt @@ -30,7 +30,7 @@ class LeaveSpaceStateProvider : PreviewParameterProvider { persistentListOf( aSelectableSpaceRoom( spaceRoom = aSpaceRoom( - name = "A long space name that should be truncated", + rawName = "A long space name that should be truncated", worldReadable = true, ), isLastAdmin = true, diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt index c0a88c38f5..4f9ec4c561 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt @@ -25,7 +25,7 @@ open class SpaceStateProvider : PreviewParameterProvider { aSpaceState(), aSpaceState( parentSpace = aSpaceRoom( - name = null, + rawName = null, numJoinedMembers = 5, childrenCount = 10, worldReadable = true, diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt index 1e89fd2e98..c06bbcc723 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt @@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.user.MatrixUser data class SpaceRoom( - val name: String?, + val rawName: String?, val avatarUrl: String?, val canonicalAlias: RoomAlias?, val childrenCount: Int, @@ -32,6 +32,18 @@ data class SpaceRoom( * The via parameters of the room. */ val via: List, + val isDirect: Boolean?, ) { val isSpace = roomType == RoomType.Space + + /** + * Temporary logic to compute a name for direct rooms with no name. + * This will be replaced by sdk logic in the future. + */ + val name = if (rawName == null && isDirect == true && heroes.size == 1) { + val dmRecipient = heroes.first() + dmRecipient.displayName + } else { + rawName + } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceRoomMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceRoomMapper.kt index 7032d052d8..248366aa03 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceRoomMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceRoomMapper.kt @@ -24,7 +24,7 @@ class SpaceRoomMapper { guestCanJoin = spaceRoom.guestCanJoin, heroes = spaceRoom.heroes.orEmpty().map { it.map() }, joinRule = spaceRoom.joinRule?.map(), - name = spaceRoom.name, + rawName = spaceRoom.name, numJoinedMembers = spaceRoom.numJoinedMembers.toInt(), roomId = RoomId(spaceRoom.roomId), roomType = spaceRoom.roomType.map(), @@ -32,6 +32,7 @@ class SpaceRoomMapper { topic = spaceRoom.topic, worldReadable = spaceRoom.worldReadable.orFalse(), via = spaceRoom.via, + isDirect = spaceRoom.isDirect, ) } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomProvider.kt index bfdfeeac59..a355dd132c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomProvider.kt @@ -18,23 +18,31 @@ class SpaceRoomProvider : PreviewParameterProvider { override val values: Sequence = sequenceOf( aSpaceRoom( roomType = RoomType.Room, - name = "Room name with topic", + rawName = "Room name with topic", topic = "Room topic that is quite long and might be truncated" ), aSpaceRoom( roomType = RoomType.Room, - name = "Room name no topic", + rawName = "Room name no topic", state = CurrentUserMembership.LEFT, ), aSpaceRoom( roomType = RoomType.Room, - name = "Room name with topic", + rawName = null, + isDirect = true, + heroes = listOf(aMatrixUser(displayName = "Alice")), + state = CurrentUserMembership.JOINED, + numJoinedMembers = 2, + ), + aSpaceRoom( + roomType = RoomType.Room, + rawName = "Room name with topic", topic = "Room topic that is quite long and might be truncated", state = CurrentUserMembership.INVITED, ), aSpaceRoom( roomType = RoomType.Room, - name = "Room name no topic", + rawName = "Room name no topic", state = CurrentUserMembership.INVITED, ), aSpaceRoom( @@ -52,7 +60,7 @@ class SpaceRoomProvider : PreviewParameterProvider { state = CurrentUserMembership.LEFT, ), aSpaceRoom( - name = null, + rawName = null, numJoinedMembers = 5, childrenCount = 10, worldReadable = true, @@ -61,7 +69,7 @@ class SpaceRoomProvider : PreviewParameterProvider { state = CurrentUserMembership.INVITED, ), aSpaceRoom( - name = null, + rawName = null, numJoinedMembers = 5, childrenCount = 10, worldReadable = true, diff --git a/libraries/previewutils/src/main/kotlin/io/element/android/libraries/previewutils/room/SpaceRoomFixture.kt b/libraries/previewutils/src/main/kotlin/io/element/android/libraries/previewutils/room/SpaceRoomFixture.kt index f3b38c241a..510a59a7cb 100644 --- a/libraries/previewutils/src/main/kotlin/io/element/android/libraries/previewutils/room/SpaceRoomFixture.kt +++ b/libraries/previewutils/src/main/kotlin/io/element/android/libraries/previewutils/room/SpaceRoomFixture.kt @@ -16,7 +16,7 @@ import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.user.MatrixUser fun aSpaceRoom( - name: String? = "Space name", + rawName: String? = "Space name", avatarUrl: String? = null, canonicalAlias: RoomAlias? = null, childrenCount: Int = 0, @@ -29,9 +29,10 @@ fun aSpaceRoom( state: CurrentUserMembership? = null, topic: String? = null, worldReadable: Boolean = false, + isDirect: Boolean? = null, via: List = emptyList(), ) = SpaceRoom( - name = name, + rawName = rawName, avatarUrl = avatarUrl, canonicalAlias = canonicalAlias, childrenCount = childrenCount, @@ -45,4 +46,5 @@ fun aSpaceRoom( topic = topic, worldReadable = worldReadable, via = via, + isDirect = isDirect ) From 77647a3f11d6796ef1c1a7cc53954413a67eb61a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 1 Oct 2025 18:22:31 +0200 Subject: [PATCH 55/73] Let MatrixClient exposes `val` instead of `fun` for the services. --- .../android/appnav/LoggedInFlowNode.kt | 8 +-- .../android/appnav/di/MatrixSessionCache.kt | 5 +- .../android/appnav/di/SyncOrchestrator.kt | 15 +++--- .../android/appnav/SyncOrchestratorTest.kt | 4 +- .../appnav/di/MatrixSessionCacheTest.kt | 11 ++-- .../call/impl/ui/CallScreenPresenter.kt | 2 +- .../home/impl/roomlist/RoomListPresenter.kt | 3 +- .../impl/roomlist/RoomListPresenterTest.kt | 2 +- .../createaccount/CreateAccountPresenter.kt | 2 +- .../messages/impl/MessagesFlowNode.kt | 50 ++++++++++-------- .../impl/DefaultMessagesEntryPointTest.kt | 6 ++- .../impl/reporter/DefaultBugReporter.kt | 4 +- .../roomdetails/impl/RoomDetailsPresenter.kt | 4 +- .../impl/RoomDetailsPresenterTest.kt | 2 +- .../impl/reset/ResetIdentityFlowManager.kt | 6 +-- .../reset/ResetIdentityFlowManagerTest.kt | 4 +- .../features/space/impl/SpaceFlowNode.kt | 6 +-- .../space/impl/DefaultSpaceEntryPointTest.kt | 7 +-- .../libraries/matrix/api/MatrixClient.kt | 18 +++---- .../libraries/matrix/impl/RustMatrixClient.kt | 52 +++++-------------- .../matrix/impl/di/SessionMatrixModule.kt | 20 ++++--- .../impl/encryption/RustEncryptionService.kt | 2 +- .../libraries/matrix/test/FakeMatrixClient.kt | 39 ++++---------- .../libraries/matrix/ui/safety/Avatars.kt | 2 +- .../push/impl/DefaultPusherSubscriber.kt | 4 +- .../DefaultNotifiableEventResolver.kt | 4 +- .../DefaultOnMissedCallNotificationHandler.kt | 2 +- 27 files changed, 129 insertions(+), 155 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 66df9a6dd5..b0fc707d07 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -141,8 +141,8 @@ class LoggedInFlowNode( } private val loggedInFlowProcessor = LoggedInEventProcessor( - snackbarDispatcher, - matrixClient.roomMembershipObserver(), + snackbarDispatcher = snackbarDispatcher, + roomMembershipObserver = matrixClient.roomMembershipObserver, ) private val verificationListener = object : SessionVerificationServiceListener { @@ -189,7 +189,7 @@ class LoggedInFlowNode( // TODO We do not support Space yet, so directly navigate to main space appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE) loggedInFlowProcessor.observeEvents(sessionCoroutineScope) - matrixClient.sessionVerificationService().setListener(verificationListener) + matrixClient.sessionVerificationService.setListener(verificationListener) mediaPreviewConfigMigration() sessionCoroutineScope.launch { @@ -218,7 +218,7 @@ class LoggedInFlowNode( appNavigationStateService.onLeavingSpace(id) appNavigationStateService.onLeavingSession(id) loggedInFlowProcessor.stopObserving() - matrixClient.sessionVerificationService().setListener(null) + matrixClient.sessionVerificationService.setListener(null) } ) setupSendingQueue() diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt index 78b9617eae..ce80ac7207 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt @@ -109,7 +109,10 @@ class MatrixSessionCache( } private fun onNewMatrixClient(matrixClient: MatrixClient) { - val syncOrchestrator = syncOrchestratorFactory.create(matrixClient) + val syncOrchestrator = syncOrchestratorFactory.create( + syncService = matrixClient.syncService, + sessionCoroutineScope = matrixClient.sessionCoroutineScope, + ) sessionIdsToMatrixSession[matrixClient.sessionId] = InMemoryMatrixSession( matrixClient = matrixClient, syncOrchestrator = syncOrchestrator, diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt index b88c4269a0..2561fd3ac7 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt @@ -15,9 +15,10 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.childScope -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.services.appnavstate.api.AppForegroundStateService +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce @@ -32,21 +33,23 @@ import kotlin.time.Duration.Companion.seconds @AssistedInject class SyncOrchestrator( - @Assisted matrixClient: MatrixClient, + @Assisted private val syncService: SyncService, + @Assisted sessionCoroutineScope: CoroutineScope, private val appForegroundStateService: AppForegroundStateService, private val networkMonitor: NetworkMonitor, dispatchers: CoroutineDispatchers, ) { @AssistedFactory interface Factory { - fun create(matrixClient: MatrixClient): SyncOrchestrator + fun create( + syncService: SyncService, + sessionCoroutineScope: CoroutineScope, + ): SyncOrchestrator } - private val syncService = matrixClient.syncService() - private val tag = "SyncOrchestrator" - private val coroutineScope = matrixClient.sessionCoroutineScope.childScope(dispatchers.io, tag) + private val coroutineScope = sessionCoroutineScope.childScope(dispatchers.io, tag) private val started = AtomicBoolean(false) diff --git a/appnav/src/test/kotlin/io/element/android/appnav/SyncOrchestratorTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/SyncOrchestratorTest.kt index 2c143df095..f26df83a56 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/SyncOrchestratorTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/SyncOrchestratorTest.kt @@ -11,7 +11,6 @@ import io.element.android.appnav.di.SyncOrchestrator import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.libraries.matrix.api.sync.SyncState -import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.tests.testutils.WarmUpRule @@ -385,7 +384,8 @@ class SyncOrchestratorTest { networkMonitor: FakeNetworkMonitor = FakeNetworkMonitor(), appForegroundStateService: FakeAppForegroundStateService = FakeAppForegroundStateService(), ) = SyncOrchestrator( - matrixClient = FakeMatrixClient(syncService = syncService, sessionCoroutineScope = backgroundScope), + syncService = syncService, + sessionCoroutineScope = backgroundScope, networkMonitor = networkMonitor, appForegroundStateService = appForegroundStateService, dispatchers = testCoroutineDispatchers(), diff --git a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt index 47237d5f77..6df80ee95d 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt @@ -10,12 +10,13 @@ package io.element.android.appnav.di import com.bumble.appyx.core.state.MutableSavedStateMapImpl import com.google.common.truth.Truth.assertThat import io.element.android.features.networkmonitor.test.FakeNetworkMonitor -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @@ -117,9 +118,13 @@ class MatrixSessionCacheTest { } private fun TestScope.createSyncOrchestratorFactory() = object : SyncOrchestrator.Factory { - override fun create(matrixClient: MatrixClient): SyncOrchestrator { + override fun create( + syncService: SyncService, + sessionCoroutineScope: CoroutineScope, + ): SyncOrchestrator { return SyncOrchestrator( - matrixClient, + syncService = syncService, + sessionCoroutineScope = sessionCoroutineScope, appForegroundStateService = FakeAppForegroundStateService(), networkMonitor = FakeNetworkMonitor(), dispatchers = testCoroutineDispatchers(), diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt index 366352a272..06929093f5 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt @@ -242,7 +242,7 @@ class CallScreenPresenter( } coroutineScope.launch { Timber.d("Observing sync state in-call for sessionId: ${roomCallType.sessionId}") - client.syncService().syncState + client.syncService.syncState .collect { state -> if (state != SyncState.Running) { appForegroundStateService.updateIsInCallState(true) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt index b8e299c5e9..7b51e4797e 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt @@ -39,7 +39,6 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.timeline.ReceiptType @@ -84,7 +83,7 @@ class RoomListPresenter( private val appPreferencesStore: AppPreferencesStore, private val seenInvitesStore: SeenInvitesStore, ) : Presenter { - private val encryptionService: EncryptionService = client.encryptionService() + private val encryptionService = client.encryptionService @Composable override fun present(): RoomListState { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index 7ad58f2832..bde004cf82 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -616,7 +616,7 @@ class RoomListPresenterTest { roomLastMessageFormatter = roomLastMessageFormatter, ), coroutineDispatchers = testCoroutineDispatchers(), - notificationSettingsService = client.notificationSettingsService(), + notificationSettingsService = client.notificationSettingsService, sessionCoroutineScope = backgroundScope, dateTimeObserver = FakeDateTimeObserver(), ), diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt index d838c971fc..a3aec0eb81 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt @@ -82,7 +82,7 @@ class CreateAccountPresenter( tryOrNull { // Wait until the session is verified val client = clientProvider.getOrRestore(sessionId).getOrThrow() - val sessionVerificationService = client.sessionVerificationService() + val sessionVerificationService = client.sessionVerificationService withTimeout(10.seconds) { sessionVerificationService.sessionVerifiedStatus.first { it.isVerified() } } } loggedInState.value = AsyncAction.Success(sessionId) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt index af613e2520..82aafcf545 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt @@ -62,9 +62,9 @@ import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.dateformatter.api.toHumanReadableDuration import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias @@ -73,6 +73,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.alias.matches import io.element.android.libraries.matrix.api.room.joinedRoomMembers +import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache @@ -95,7 +96,8 @@ import kotlinx.parcelize.Parcelize class MessagesFlowNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val matrixClient: MatrixClient, + private val roomListService: RoomListService, + private val sessionId: SessionId, private val sendLocationEntryPoint: SendLocationEntryPoint, private val showLocationEntryPoint: ShowLocationEntryPoint, private val createPollEntryPoint: CreatePollEntryPoint, @@ -194,7 +196,7 @@ class MessagesFlowNode( } .launchIn(lifecycleScope) - matrixClient.roomListService + roomListService .allRooms .summaries .onEach { @@ -221,11 +223,13 @@ class MessagesFlowNode( } override fun onPreviewAttachments(attachments: ImmutableList, inReplyToEventId: EventId?) { - backstack.push(NavTarget.AttachmentPreview( - attachment = attachments.first(), - timelineMode = Timeline.Mode.Live, - inReplyToEventId = inReplyToEventId, - )) + backstack.push( + NavTarget.AttachmentPreview( + attachment = attachments.first(), + timelineMode = Timeline.Mode.Live, + inReplyToEventId = inReplyToEventId, + ) + ) } override fun onUserDataClick(userId: UserId) { @@ -262,7 +266,7 @@ class MessagesFlowNode( override fun onJoinCallClick(roomId: RoomId) { val callType = CallType.RoomCall( - sessionId = matrixClient.sessionId, + sessionId = sessionId, roomId = roomId, ) analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton) @@ -348,18 +352,20 @@ class MessagesFlowNode( } is NavTarget.CreatePoll -> { createPollEntryPoint.nodeBuilder(this, buildContext) - .params(CreatePollEntryPoint.Params( - timelineMode = navTarget.timelineMode, - mode = CreatePollMode.NewPoll - )) + .params( + CreatePollEntryPoint.Params( + timelineMode = navTarget.timelineMode, + mode = CreatePollMode.NewPoll + ) + ) .build() } is NavTarget.EditPoll -> { createPollEntryPoint.nodeBuilder(this, buildContext) .params( CreatePollEntryPoint.Params( - timelineMode = navTarget.timelineMode, - mode = CreatePollMode.EditPoll(eventId = navTarget.eventId) + timelineMode = navTarget.timelineMode, + mode = CreatePollMode.EditPoll(eventId = navTarget.eventId) ) ) .build() @@ -412,11 +418,13 @@ class MessagesFlowNode( } override fun onPreviewAttachments(attachments: ImmutableList, inReplyToEventId: EventId?) { - backstack.push(NavTarget.AttachmentPreview( - attachment = attachments.first(), - timelineMode = Timeline.Mode.Thread(navTarget.threadRootId), - inReplyToEventId = inReplyToEventId, - )) + backstack.push( + NavTarget.AttachmentPreview( + attachment = attachments.first(), + timelineMode = Timeline.Mode.Thread(navTarget.threadRootId), + inReplyToEventId = inReplyToEventId, + ) + ) } override fun onUserDataClick(userId: UserId) { @@ -453,7 +461,7 @@ class MessagesFlowNode( override fun onJoinCallClick(roomId: RoomId) { val callType = CallType.RoomCall( - sessionId = matrixClient.sessionId, + sessionId = sessionId, roomId = roomId, ) analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt index a4753807cd..2de761ad69 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt @@ -30,9 +30,10 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID -import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom +import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache import io.element.android.libraries.matrix.ui.messages.RoomNamesCache import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint @@ -60,7 +61,8 @@ class DefaultMessagesEntryPointTest { MessagesFlowNode( buildContext = buildContext, plugins = plugins, - matrixClient = FakeMatrixClient(), + roomListService = FakeRoomListService(), + sessionId = A_SESSION_ID, sendLocationEntryPoint = object : SendLocationEntryPoint { override fun builder(timelineMode: Timeline.Mode) = lambdaError() }, diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt index 01b6857c0b..5787939688 100755 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt @@ -176,8 +176,8 @@ class DefaultBugReporter( .addFormDataPart("branch_name", buildMeta.gitBranchName) userId?.let { matrixClientProvider.getOrNull(it)?.let { client -> - val curveKey = client.encryptionService().deviceCurve25519() - val edKey = client.encryptionService().deviceEd25519() + val curveKey = client.encryptionService.deviceCurve25519() + val edKey = client.encryptionService.deviceEd25519() if (curveKey != null && edKey != null) { builder.addFormDataPart("device_keys", "curve25519:$curveKey, ed25519:$edKey") } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 0071aced5d..c7938b609f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -143,12 +143,12 @@ class RoomDetailsPresenter( } RoomDetailsEvent.MuteNotification -> { scope.launch(dispatchers.io) { - client.notificationSettingsService().muteRoom(room.roomId) + notificationSettingsService.muteRoom(room.roomId) } } RoomDetailsEvent.UnmuteNotification -> { scope.launch(dispatchers.io) { - client.notificationSettingsService().unmuteRoom(room.roomId, isEncrypted, room.isOneToOne) + notificationSettingsService.unmuteRoom(room.roomId, isEncrypted, room.isOneToOne) } } is RoomDetailsEvent.SetFavorite -> scope.setFavorite(event.isFavorite) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt index bfcfa184cb..695168aa16 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt @@ -104,7 +104,7 @@ class RoomDetailsPresenterTest { client = matrixClient, room = room, featureFlagService = featureFlagService, - notificationSettingsService = matrixClient.notificationSettingsService(), + notificationSettingsService = matrixClient.notificationSettingsService, roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory, leaveRoomPresenter = { leaveRoomState }, roomCallStatePresenter = { aStandByCallState() }, diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt index fe6a86a357..4ffaa9c344 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt @@ -10,7 +10,7 @@ package io.element.android.features.securebackup.impl.reset import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.di.annotations.SessionCoroutineScope -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus @@ -24,7 +24,7 @@ import kotlinx.coroutines.launch @Inject class ResetIdentityFlowManager( - private val matrixClient: MatrixClient, + private val encryptionService: EncryptionService, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val sessionVerificationService: SessionVerificationService, ) { @@ -46,7 +46,7 @@ class ResetIdentityFlowManager( resetHandleFlow.value = AsyncData.Loading() sessionCoroutineScope.launch { - matrixClient.encryptionService().startIdentityReset() + encryptionService.startIdentityReset() .onSuccess { handle -> resetHandleFlow.value = AsyncData.Success(handle) } diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt index a26d6fabef..702b10a1bf 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt @@ -12,7 +12,6 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus -import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.encryption.FakeIdentityPasswordResetHandle import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService @@ -130,10 +129,9 @@ class ResetIdentityFlowManagerTest { private fun TestScope.createFlowManager( encryptionService: FakeEncryptionService = FakeEncryptionService(), - client: FakeMatrixClient = FakeMatrixClient(encryptionService = encryptionService), sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), ) = ResetIdentityFlowManager( - matrixClient = client, + encryptionService = encryptionService, sessionCoroutineScope = this, sessionVerificationService = sessionVerificationService, ) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt index fffdeb6246..78472c7b31 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt @@ -32,8 +32,8 @@ import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.DependencyInjectionGraphOwner import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceService import kotlinx.parcelize.Parcelize @ContributesNode(SessionScope::class) @@ -41,7 +41,7 @@ import kotlinx.parcelize.Parcelize class SpaceFlowNode( @Assisted val buildContext: BuildContext, @Assisted plugins: List, - matrixClient: MatrixClient, + spaceService: SpaceService, graphFactory: SpaceFlowGraph.Factory, ) : BaseFlowNode( backstack = BackStack( @@ -53,7 +53,7 @@ class SpaceFlowNode( ), DependencyInjectionGraphOwner { private val inputs: SpaceEntryPoint.Inputs = inputs() private val callback = plugins.filterIsInstance().single() - private val spaceRoomList = matrixClient.spaceService.spaceRoomList(inputs.roomId) + private val spaceRoomList = spaceService.spaceRoomList(inputs.roomId) override val graph = graphFactory.create(spaceRoomList) sealed interface NavTarget : Parcelable { diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/DefaultSpaceEntryPointTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/DefaultSpaceEntryPointTest.kt index 007c28e3a6..17823ba72b 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/DefaultSpaceEntryPointTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/DefaultSpaceEntryPointTest.kt @@ -15,7 +15,6 @@ import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.features.space.impl.di.FakeSpaceFlowGraph import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.test.A_ROOM_ID -import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList import io.element.android.libraries.matrix.test.spaces.FakeSpaceService import io.element.android.tests.testutils.lambda.lambdaError @@ -38,10 +37,8 @@ class DefaultSpaceEntryPointTest { SpaceFlowNode( buildContext = buildContext, plugins = plugins, - matrixClient = FakeMatrixClient( - spaceService = FakeSpaceService( - spaceRoomListResult = { _: RoomId -> FakeSpaceRoomList(A_ROOM_ID) } - ) + spaceService = FakeSpaceService( + spaceRoomListResult = { _: RoomId -> FakeSpaceRoomList(A_ROOM_ID) } ), graphFactory = FakeSpaceFlowGraph.Factory ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 5c495c5fd7..8323add7d3 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -49,9 +49,18 @@ interface MatrixClient { val userProfile: StateFlow val roomListService: RoomListService val spaceService: SpaceService + val syncService: SyncService + val sessionVerificationService: SessionVerificationService + val pushersService: PushersService + val notificationService: NotificationService + val notificationSettingsService: NotificationSettingsService + val encryptionService: EncryptionService + val roomDirectoryService: RoomDirectoryService + val mediaPreviewService: MediaPreviewService val mediaLoader: MatrixMediaLoader val sessionCoroutineScope: CoroutineScope val ignoredUsersFlow: StateFlow> + val roomMembershipObserver: RoomMembershipObserver suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom? suspend fun getRoom(roomId: RoomId): BaseRoom? suspend fun findDM(userId: UserId): Result @@ -68,14 +77,6 @@ interface MatrixClient { suspend fun joinRoom(roomId: RoomId): Result suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List): Result suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List): Result - fun syncService(): SyncService - fun sessionVerificationService(): SessionVerificationService - fun pushersService(): PushersService - fun notificationService(): NotificationService - fun notificationSettingsService(): NotificationSettingsService - fun encryptionService(): EncryptionService - fun roomDirectoryService(): RoomDirectoryService - fun mediaPreviewService(): MediaPreviewService suspend fun getCacheSize(): Long /** @@ -97,7 +98,6 @@ interface MatrixClient { suspend fun getUserProfile(): Result suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result suspend fun uploadMedia(mimeType: String, data: ByteArray): Result - fun roomMembershipObserver(): RoomMembershipObserver /** * Get a room info flow for a given room ID. diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index a84a7bc164..619ab95537 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -23,13 +23,8 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset -import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.media.MatrixMediaLoader -import io.element.android.libraries.matrix.api.media.MediaPreviewService -import io.element.android.libraries.matrix.api.notification.NotificationService -import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.oidc.AccountManagementAction -import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -39,16 +34,13 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.api.room.join.JoinRule -import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion -import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService import io.element.android.libraries.matrix.impl.exception.mapClientException import io.element.android.libraries.matrix.impl.mapper.map @@ -147,29 +139,29 @@ class RustMatrixClient( private val innerRoomListService = innerSyncService.roomListService() private val innerSpaceService = innerClient.spaceService() - private val roomMembershipObserver = RoomMembershipObserver() + override val roomMembershipObserver = RoomMembershipObserver() - private val rustSyncService = RustSyncService( + override val syncService = RustSyncService( inner = innerSyncService, dispatcher = sessionDispatcher, sessionCoroutineScope = sessionCoroutineScope ) - private val pushersService = RustPushersService( + override val pushersService = RustPushersService( client = innerClient, dispatchers = dispatchers, ) private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(innerSyncService) private val innerNotificationClient = runBlocking { innerClient.notificationClient(notificationProcessSetup) } - private val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock) - private val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers) - private val encryptionService = RustEncryptionService( + override val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock) + override val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers) + override val encryptionService = RustEncryptionService( client = innerClient, - syncService = rustSyncService, + syncService = syncService, sessionCoroutineScope = sessionCoroutineScope, dispatchers = dispatchers, ) - private val roomDirectoryService = RustRoomDirectoryService( + override val roomDirectoryService = RustRoomDirectoryService( client = innerClient, sessionDispatcher = sessionDispatcher, ) @@ -196,9 +188,9 @@ class RustMatrixClient( sessionDispatcher = sessionDispatcher, ) - private val verificationService = RustSessionVerificationService( + override val sessionVerificationService = RustSessionVerificationService( client = innerClient, - isSyncServiceReady = rustSyncService.syncState.map { it == SyncState.Running }, + isSyncServiceReady = syncService.syncState.map { it == SyncState.Running }, sessionCoroutineScope = sessionCoroutineScope, ) @@ -227,7 +219,7 @@ class RustMatrixClient( innerClient = innerClient, ) - private val mediaPreviewService = RustMediaPreviewService( + override val mediaPreviewService = RustMediaPreviewService( sessionCoroutineScope = sessionCoroutineScope, innerClient = innerClient, sessionDispatcher = sessionDispatcher, @@ -538,33 +530,17 @@ class RustMatrixClient( }.mapFailure { it.mapClientException() } } - override fun syncService(): SyncService = rustSyncService - - override fun sessionVerificationService(): SessionVerificationService = verificationService - - override fun pushersService(): PushersService = pushersService - - override fun notificationService(): NotificationService = notificationService - - override fun encryptionService(): EncryptionService = encryptionService - - override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService - - override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService - - override fun mediaPreviewService(): MediaPreviewService = mediaPreviewService - internal suspend fun destroy() { innerNotificationClient.close() roomFactory.destroy() - rustSyncService.destroy() + syncService.destroy() notificationSettingsService.destroy() notificationProcessSetup.destroy() sessionCoroutineScope.cancel() clientDelegateTaskHandle?.cancelAndDestroy() - verificationService.destroy() + sessionVerificationService.destroy() sessionDelegate.clearCurrentClient() innerRoomListService.close() @@ -674,8 +650,6 @@ class RustMatrixClient( } } - override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver - override fun getRoomInfoFlow(roomId: RoomId): Flow> { return mxCallbackFlow { val roomNotFound = innerRoomListService.roomOrNull(roomId.value).use { it == null } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt index 4d1f244bd2..0482cf1dcd 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomlist.RoomListService +import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.verification.SessionVerificationService import kotlinx.coroutines.CoroutineScope @@ -35,17 +36,17 @@ object SessionMatrixModule { @Provides fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService { - return matrixClient.sessionVerificationService() + return matrixClient.sessionVerificationService } @Provides fun providesNotificationSettingsService(matrixClient: MatrixClient): NotificationSettingsService { - return matrixClient.notificationSettingsService() + return matrixClient.notificationSettingsService } @Provides fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver { - return matrixClient.roomMembershipObserver() + return matrixClient.roomMembershipObserver } @Provides @@ -55,12 +56,12 @@ object SessionMatrixModule { @Provides fun providesSyncService(matrixClient: MatrixClient): SyncService { - return matrixClient.syncService() + return matrixClient.syncService } @Provides fun providesEncryptionService(matrixClient: MatrixClient): EncryptionService { - return matrixClient.encryptionService() + return matrixClient.encryptionService } @Provides @@ -76,11 +77,16 @@ object SessionMatrixModule { @Provides fun providesRoomDirectoryService(matrixClient: MatrixClient): RoomDirectoryService { - return matrixClient.roomDirectoryService() + return matrixClient.roomDirectoryService } @Provides fun providesMediaPreviewService(matrixClient: MatrixClient): MediaPreviewService { - return matrixClient.mediaPreviewService() + return matrixClient.mediaPreviewService + } + + @Provides + fun providesSpaceService(matrixClient: MatrixClient): SpaceService { + return matrixClient.spaceService } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt index 977663c883..74aeda9694 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt @@ -46,7 +46,7 @@ import org.matrix.rustcomponents.sdk.BackupUploadState as RustBackupUploadState import org.matrix.rustcomponents.sdk.EnableRecoveryProgress as RustEnableRecoveryProgress import org.matrix.rustcomponents.sdk.SteadyStateException as RustSteadyStateException -internal class RustEncryptionService( +class RustEncryptionService( client: Client, syncService: RustSyncService, sessionCoroutineScope: CoroutineScope, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 67e7561972..4443591eaa 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -15,13 +15,9 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters -import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaPreviewService -import io.element.android.libraries.matrix.api.notification.NotificationService -import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.oidc.AccountManagementAction -import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.NotJoinedRoom @@ -34,7 +30,6 @@ import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader import io.element.android.libraries.matrix.test.media.FakeMediaPreviewService @@ -69,14 +64,15 @@ class FakeMatrixClient( override val roomListService: RoomListService = FakeRoomListService(), override val spaceService: SpaceService = FakeSpaceService(), override val mediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(), - private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), - private val pushersService: FakePushersService = FakePushersService(), - private val notificationService: FakeNotificationService = FakeNotificationService(), - private val notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), - private val syncService: FakeSyncService = FakeSyncService(), - private val encryptionService: FakeEncryptionService = FakeEncryptionService(), - private val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(), - private val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(), + override val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), + override val pushersService: FakePushersService = FakePushersService(), + override val notificationService: FakeNotificationService = FakeNotificationService(), + override val notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), + override val syncService: FakeSyncService = FakeSyncService(), + override val encryptionService: FakeEncryptionService = FakeEncryptionService(), + override val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(), + override val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(), + override val roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(), private val accountManagementUrlResult: (AccountManagementAction?) -> Result = { lambdaError() }, private val resolveRoomAliasResult: (RoomAlias) -> Result> = { Result.success( @@ -174,10 +170,6 @@ class FakeMatrixClient( return searchUserResults[searchTerm] ?: Result.failure(IllegalStateException("No response defined for $searchTerm")) } - override fun syncService() = syncService - - override fun roomDirectoryService() = roomDirectoryService - override suspend fun getCacheSize(): Long { return 0 } @@ -238,19 +230,6 @@ class FakeMatrixClient( return knockRoomLambda(roomIdOrAlias, message, serverNames) } - override fun sessionVerificationService(): SessionVerificationService = sessionVerificationService - - override fun pushersService(): PushersService = pushersService - - override fun notificationService(): NotificationService = notificationService - override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService - override fun encryptionService(): EncryptionService = encryptionService - override fun mediaPreviewService(): MediaPreviewService = mediaPreviewService - - override fun roomMembershipObserver(): RoomMembershipObserver { - return RoomMembershipObserver() - } - // Mocks fun givenCreateRoomResult(result: Result) { diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/safety/Avatars.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/safety/Avatars.kt index 0eb2b37ea4..7e8573a34c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/safety/Avatars.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/safety/Avatars.kt @@ -17,7 +17,7 @@ import io.element.android.libraries.matrix.api.MatrixClient @Composable fun MatrixClient.rememberHideInvitesAvatar(): State { return remember { - mediaPreviewService() + mediaPreviewService .mediaPreviewConfigFlow .mapState { config -> config.hideInviteAvatar } }.collectAsState() diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPusherSubscriber.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPusherSubscriber.kt index 7b7a6a33e8..7dbe4e795e 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPusherSubscriber.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPusherSubscriber.kt @@ -50,7 +50,7 @@ class DefaultPusherSubscriber( Timber.tag(loggerTag.value) .d("Unnecessary to register again the same pusher, but do it in case the pusher has been removed from the server") } - return matrixClient.pushersService() + return matrixClient.pushersService .setHttpPusher( createHttpPusher(pushKey, gateway, matrixClient.sessionId) ) @@ -100,7 +100,7 @@ class DefaultPusherSubscriber( gateway: String, ): Result { val userDataStore = userPushStoreFactory.getOrCreate(matrixClient.sessionId) - return matrixClient.pushersService() + return matrixClient.pushersService .unsetHttpPusher( unsetHttpPusherData = UnsetHttpPusherData( pushKey = pushKey, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 38a1d4f753..868c7e767a 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -98,7 +98,7 @@ class DefaultNotifiableEventResolver( val ids = notificationEventRequests.groupBy { it.roomId }.mapValues { (_, value) -> value.map { it.eventId } } // TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event - val notificationsResult = client.notificationService().getNotifications(ids) + val notificationsResult = client.notificationService.getNotifications(ids) if (notificationsResult.isFailure) { val exception = notificationsResult.exceptionOrNull() @@ -131,7 +131,7 @@ class DefaultNotifiableEventResolver( ): Result = runCatchingExceptions { when (val content = this.content) { is NotificationContent.MessageLike.RoomMessage -> { - val showMediaPreview = client.mediaPreviewService().getMediaPreviewValue() == MediaPreviewValue.On + val showMediaPreview = client.mediaPreviewService.getMediaPreviewValue() == MediaPreviewValue.On val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId) val messageBody = descriptionFromMessageContent(content, senderDisambiguatedDisplayName) val notifiableMessageEvent = buildNotifiableMessageEvent( diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultOnMissedCallNotificationHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultOnMissedCallNotificationHandler.kt index dbabb33058..084ad8d832 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultOnMissedCallNotificationHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultOnMissedCallNotificationHandler.kt @@ -30,7 +30,7 @@ class DefaultOnMissedCallNotificationHandler( ) { // Resolve the event and add a notification for it, at this point it should no longer be a ringing one val notificationData = matrixClientProvider.getOrRestore(sessionId).getOrNull() - ?.notificationService() + ?.notificationService ?.getNotifications(mapOf(roomId to listOf(eventId))) ?.getOrNull() ?.get(eventId) From e0dffa4a46eed6716c0eb1e821025e913bc7156c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 11:49:43 +0200 Subject: [PATCH 56/73] Naming convention --- .../android/libraries/matrix/impl/di/SessionMatrixModule.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt index 0482cf1dcd..178eef4d28 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt @@ -65,13 +65,13 @@ object SessionMatrixModule { } @Provides - fun provideMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader { + fun providesMatrixMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader { return matrixClient.mediaLoader } @SessionCoroutineScope @Provides - fun provideSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope { + fun providesSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope { return matrixClient.sessionCoroutineScope } From cef55121cc2fa652a93ec48952cec3651c65bf4e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 11:53:39 +0200 Subject: [PATCH 57/73] Naming convention and use MatrixMediaLoader instead of MatrixClient for Coil factories. --- .../android/libraries/matrix/api/MatrixClient.kt | 2 +- .../android/libraries/matrix/impl/RustMatrixClient.kt | 2 +- .../libraries/matrix/impl/di/SessionMatrixModule.kt | 2 +- .../android/libraries/matrix/test/FakeMatrixClient.kt | 2 +- .../matrix/ui/media/AvatarDataFetcherFactory.kt | 6 +++--- .../libraries/matrix/ui/media/ImageLoaderFactories.kt | 10 +++++----- .../libraries/matrix/ui/media/ImageLoaderHolder.kt | 2 +- .../matrix/ui/media/MediaRequestDataFetcherFactory.kt | 6 +++--- .../matrix/ui/media/DefaultImageLoaderHolderTest.kt | 10 +++++----- .../matrix/ui/media/FakeLoggedInImageLoaderFactory.kt | 8 ++++---- .../push/impl/notifications/NotificationMediaRepo.kt | 2 +- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 8323add7d3..5f116612b1 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -57,7 +57,7 @@ interface MatrixClient { val encryptionService: EncryptionService val roomDirectoryService: RoomDirectoryService val mediaPreviewService: MediaPreviewService - val mediaLoader: MatrixMediaLoader + val matrixMediaLoader: MatrixMediaLoader val sessionCoroutineScope: CoroutineScope val ignoredUsersFlow: StateFlow> val roomMembershipObserver: RoomMembershipObserver diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 619ab95537..33fe0e5056 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -213,7 +213,7 @@ class RustMatrixClient( featureFlagService = featureFlagService, ) - override val mediaLoader: MatrixMediaLoader = RustMediaLoader( + override val matrixMediaLoader: MatrixMediaLoader = RustMediaLoader( baseCacheDirectory = baseCacheDirectory, dispatchers = dispatchers, innerClient = innerClient, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt index 178eef4d28..37cf406f5f 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/SessionMatrixModule.kt @@ -66,7 +66,7 @@ object SessionMatrixModule { @Provides fun providesMatrixMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader { - return matrixClient.mediaLoader + return matrixClient.matrixMediaLoader } @SessionCoroutineScope diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 4443591eaa..431a5242f9 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -63,7 +63,7 @@ class FakeMatrixClient( private val userAvatarUrl: String? = AN_AVATAR_URL, override val roomListService: RoomListService = FakeRoomListService(), override val spaceService: SpaceService = FakeSpaceService(), - override val mediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(), + override val matrixMediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(), override val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), override val pushersService: FakePushersService = FakePushersService(), override val notificationService: FakeNotificationService = FakeNotificationService(), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt index e176c4c03b..c852be62f5 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt @@ -11,10 +11,10 @@ import coil3.ImageLoader import coil3.fetch.Fetcher import coil3.request.Options import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.media.MatrixMediaLoader internal class AvatarDataFetcherFactory( - private val client: MatrixClient + private val matrixMediaLoader: MatrixMediaLoader ) : Fetcher.Factory { override fun create( data: AvatarData, @@ -22,7 +22,7 @@ internal class AvatarDataFetcherFactory( imageLoader: ImageLoader ): Fetcher { return CoilMediaFetcher( - mediaLoader = client.mediaLoader, + mediaLoader = matrixMediaLoader, mediaData = data.toMediaRequestData(), ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt index dc36eb3878..54a1a21e22 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt @@ -18,11 +18,11 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Provider import io.element.android.libraries.di.annotations.ApplicationContext -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import okhttp3.OkHttpClient interface LoggedInImageLoaderFactory { - fun newImageLoader(matrixClient: MatrixClient): ImageLoader + fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader } @ContributesBinding(AppScope::class) @@ -31,7 +31,7 @@ class DefaultLoggedInImageLoaderFactory( @ApplicationContext private val context: Context, private val okHttpClient: Provider, ) : LoggedInImageLoaderFactory { - override fun newImageLoader(matrixClient: MatrixClient): ImageLoader { + override fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader { return ImageLoader.Builder(context) .components { add( @@ -50,8 +50,8 @@ class DefaultLoggedInImageLoaderFactory( } add(AvatarDataKeyer()) add(MediaRequestDataKeyer()) - add(AvatarDataFetcherFactory(matrixClient)) - add(MediaRequestDataFetcherFactory(matrixClient)) + add(AvatarDataFetcherFactory(matrixMediaLoader)) + add(MediaRequestDataFetcherFactory(matrixMediaLoader)) } .build() } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderHolder.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderHolder.kt index 82080c66cc..6720eaae0f 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderHolder.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderHolder.kt @@ -49,7 +49,7 @@ class DefaultImageLoaderHolder( return synchronized(map) { map.getOrPut(client.sessionId) { loggedInImageLoaderFactory - .newImageLoader(client) + .newImageLoader(client.matrixMediaLoader) } } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt index 2ac2ebe511..bc6cb7663c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt @@ -10,10 +10,10 @@ package io.element.android.libraries.matrix.ui.media import coil3.ImageLoader import coil3.fetch.Fetcher import coil3.request.Options -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.media.MatrixMediaLoader internal class MediaRequestDataFetcherFactory( - private val client: MatrixClient + private val matrixMediaLoader: MatrixMediaLoader, ) : Fetcher.Factory { override fun create( data: MediaRequestData, @@ -21,7 +21,7 @@ internal class MediaRequestDataFetcherFactory( imageLoader: ImageLoader ): Fetcher { return CoilMediaFetcher( - mediaLoader = client.mediaLoader, + mediaLoader = matrixMediaLoader, mediaData = data, ) } diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/DefaultImageLoaderHolderTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/DefaultImageLoaderHolderTest.kt index 5b3bc33d9f..a30305176b 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/DefaultImageLoaderHolderTest.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/DefaultImageLoaderHolderTest.kt @@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.ui.media import androidx.test.platform.app.InstrumentationRegistry import coil3.ImageLoader import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.sessionstorage.test.observer.FakeSessionObserver @@ -27,7 +27,7 @@ class DefaultImageLoaderHolderTest { @Test fun `get - returns the same ImageLoader for the same client`() { val context = InstrumentationRegistry.getInstrumentation().context - val lambda = lambdaRecorder { ImageLoader.Builder(context).build() } + val lambda = lambdaRecorder { ImageLoader.Builder(context).build() } val holder = DefaultImageLoaderHolder( loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), @@ -39,14 +39,14 @@ class DefaultImageLoaderHolderTest { assert(imageLoader1 === imageLoader2) lambda.assertions() .isCalledOnce() - .with(value(client)) + .with(value(client.matrixMediaLoader)) } @Test fun `when session is deleted, the image loader is deleted`() = runTest { val context = InstrumentationRegistry.getInstrumentation().context val lambda = - lambdaRecorder { ImageLoader.Builder(context).build() } + lambdaRecorder { ImageLoader.Builder(context).build() } val sessionObserver = FakeSessionObserver() val holder = DefaultImageLoaderHolder( loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), @@ -65,7 +65,7 @@ class DefaultImageLoaderHolderTest { fun `when session is created, nothing happen`() = runTest { val context = InstrumentationRegistry.getInstrumentation().context val lambda = - lambdaRecorder { ImageLoader.Builder(context).build() } + lambdaRecorder { ImageLoader.Builder(context).build() } val sessionObserver = FakeSessionObserver() DefaultImageLoaderHolder( loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/FakeLoggedInImageLoaderFactory.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/FakeLoggedInImageLoaderFactory.kt index a4f5bbdfb7..56ee9ee653 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/FakeLoggedInImageLoaderFactory.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/media/FakeLoggedInImageLoaderFactory.kt @@ -8,12 +8,12 @@ package io.element.android.libraries.matrix.ui.media import coil3.ImageLoader -import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.media.MatrixMediaLoader class FakeLoggedInImageLoaderFactory( - private val newImageLoaderLambda: (MatrixClient) -> ImageLoader + private val newImageLoaderLambda: (MatrixMediaLoader) -> ImageLoader ) : LoggedInImageLoaderFactory { - override fun newImageLoader(matrixClient: MatrixClient): ImageLoader { - return newImageLoaderLambda(matrixClient) + override fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader { + return newImageLoaderLambda(matrixMediaLoader) } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt index 0794efe6fb..2bbc7208be 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt @@ -72,7 +72,7 @@ class DefaultNotificationMediaRepo( ): DefaultNotificationMediaRepo } - private val matrixMediaLoader = client.mediaLoader + private val matrixMediaLoader = client.matrixMediaLoader override suspend fun getMediaFile( mediaSource: MediaSource, From 5afb048928a1cc0c94a608c74625fdd88ce4c819 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Oct 2025 11:56:17 +0200 Subject: [PATCH 58/73] Use base type. --- .../libraries/matrix/test/FakeMatrixClient.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 431a5242f9..f0e296ea5d 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -15,9 +15,13 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters +import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaPreviewService +import io.element.android.libraries.matrix.api.notification.NotificationService +import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.oidc.AccountManagementAction +import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.NotJoinedRoom @@ -28,8 +32,10 @@ import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryServic import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion +import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader import io.element.android.libraries.matrix.test.media.FakeMediaPreviewService @@ -64,12 +70,12 @@ class FakeMatrixClient( override val roomListService: RoomListService = FakeRoomListService(), override val spaceService: SpaceService = FakeSpaceService(), override val matrixMediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(), - override val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), - override val pushersService: FakePushersService = FakePushersService(), - override val notificationService: FakeNotificationService = FakeNotificationService(), - override val notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), - override val syncService: FakeSyncService = FakeSyncService(), - override val encryptionService: FakeEncryptionService = FakeEncryptionService(), + override val sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(), + override val pushersService: PushersService = FakePushersService(), + override val notificationService: NotificationService = FakeNotificationService(), + override val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(), + override val syncService: SyncService = FakeSyncService(), + override val encryptionService: EncryptionService = FakeEncryptionService(), override val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(), override val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(), override val roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(), From b94925c8788f5e34d7f6531336db8d6a404401f2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 15:42:15 +0200 Subject: [PATCH 59/73] Remove unused getCacheSize File receiver. The path are manager by the sessionData now. --- .../libraries/matrix/impl/RustMatrixClient.kt | 5 ++--- .../matrix/impl/RustMatrixClientFactory.kt | 19 +++++++++---------- .../impl/RustMatrixClientFactoryTest.kt | 2 -- .../matrix/impl/RustMatrixClientTest.kt | 1 - .../RustMatrixAuthenticationServiceTest.kt | 1 - 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 33fe0e5056..aa4004d379 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -120,7 +120,6 @@ import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService class RustMatrixClient( private val innerClient: Client, - private val baseDirectory: File, private val sessionStore: SessionStore, private val appCoroutineScope: CoroutineScope, private val sessionDelegate: RustClientSessionDelegate, @@ -551,7 +550,7 @@ class RustMatrixClient( } override suspend fun getCacheSize(): Long { - return baseDirectory.getCacheSize() + return getCacheSize(includeCryptoDb = false) } override suspend fun clearCache() { @@ -714,7 +713,7 @@ class RustMatrixClient( } } - private suspend fun File.getCacheSize( + private suspend fun getCacheSize( includeCryptoDb: Boolean = false, ): Long = withContext(sessionDispatcher) { val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 572bcbfd18..35b5bcf2b9 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl import dev.zacsweers.metro.Inject import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.di.BaseDirectory import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -43,7 +42,6 @@ import java.io.File @Inject class RustMatrixClientFactory( - @BaseDirectory private val baseDirectory: File, @CacheDirectory private val cacheDirectory: File, @AppCoroutineScope private val appCoroutineScope: CoroutineScope, @@ -87,7 +85,6 @@ class RustMatrixClientFactory( return RustMatrixClient( innerClient = client, - baseDirectory = baseDirectory, sessionStore = sessionStore, appCoroutineScope = appCoroutineScope, sessionDelegate = sessionDelegate, @@ -136,13 +133,15 @@ class RustMatrixClientFactory( ) .enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite)) .threadsEnabled(featureFlagService.isFeatureEnabled(FeatureFlags.Threads), threadSubscriptions = false) - .requestConfig(RequestConfig( - timeout = 30_000uL, - retryLimit = 0u, - // Use default values for the rest - maxConcurrentRequests = null, - maxRetryTime = null, - )) + .requestConfig( + RequestConfig( + timeout = 30_000uL, + retryLimit = 0u, + // Use default values for the rest + maxConcurrentRequests = null, + maxRetryTime = null, + ) + ) .run { // Apply sliding sync version settings when (slidingSyncType) { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt index 045b5d7772..92f9438322 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt @@ -36,14 +36,12 @@ class RustMatrixClientFactoryTest { } fun TestScope.createRustMatrixClientFactory( - baseDirectory: File = File("/base"), cacheDirectory: File = File("/cache"), sessionStore: SessionStore = InMemorySessionStore( updateUserProfileResult = { _, _, _ -> }, ), clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(), ) = RustMatrixClientFactory( - baseDirectory = baseDirectory, cacheDirectory = cacheDirectory, appCoroutineScope = backgroundScope, coroutineDispatchers = testCoroutineDispatchers(), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt index 6eed2d0967..dec0f4cd4f 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt @@ -102,7 +102,6 @@ class RustMatrixClientTest { ), ) = RustMatrixClient( innerClient = client, - baseDirectory = File(""), sessionStore = sessionStore, appCoroutineScope = backgroundScope, sessionDelegate = aRustClientSessionDelegate( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt index 1cb5db91f6..490c921aa9 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt @@ -53,7 +53,6 @@ class RustMatrixAuthenticationServiceTest { val baseDirectory = File("/base") val cacheDirectory = File("/cache") val rustMatrixClientFactory = createRustMatrixClientFactory( - baseDirectory = baseDirectory, cacheDirectory = cacheDirectory, sessionStore = sessionStore, clientBuilderProvider = clientBuilderProvider, From d1cbf69af81dbe7fe75928dc5ad2d0328760b1df Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 Oct 2025 15:43:12 +0200 Subject: [PATCH 60/73] appCoroutineScope does not have to be a class member. --- .../element/android/libraries/matrix/impl/RustMatrixClient.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index aa4004d379..5852a64f37 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -121,9 +121,9 @@ import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService class RustMatrixClient( private val innerClient: Client, private val sessionStore: SessionStore, - private val appCoroutineScope: CoroutineScope, private val sessionDelegate: RustClientSessionDelegate, private val innerSyncService: ClientSyncService, + appCoroutineScope: CoroutineScope, dispatchers: CoroutineDispatchers, baseCacheDirectory: File, clock: SystemClock, From 17f9673a0fe06565fe0a3ee9101c824d98115232 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 6 Oct 2025 16:17:02 +0200 Subject: [PATCH 61/73] feature(space): introduce SpaceRoomVisibility and remove room count --- .../home/impl/spaces/HomeSpacesView.kt | 9 +--- .../features/joinroom/impl/JoinRoomView.kt | 7 +-- .../space/impl/root/SpaceStateProvider.kt | 12 +++++ .../features/space/impl/root/SpaceView.kt | 3 +- .../libraries/matrix/api/spaces/SpaceRoom.kt | 2 + .../matrix/api/spaces/SpaceRoomVisibility.kt | 26 ++++++++++ .../ui/components/SpaceHeaderRootView.kt | 4 +- .../matrix/ui/components/SpaceHeaderView.kt | 15 ++---- .../matrix/ui/components/SpaceInfoRow.kt | 49 +++++++---------- .../matrix/ui/components/SpaceRoomItemView.kt | 52 ++++++++----------- .../matrix/ui/model/SpaceExtension.kt | 28 ++++++++++ .../src/main/res/values/localazy.xml | 3 ++ 12 files changed, 122 insertions(+), 88 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoomVisibility.kt diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt index 36e0bbc56a..09604c0d94 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt @@ -33,11 +33,7 @@ fun HomeSpacesView( when (space) { CurrentSpace.Root -> { item { - SpaceHeaderRootView( - numberOfSpaces = state.spaceRooms.size, - // TODO - numberOfRooms = 0, - ) + SpaceHeaderRootView(numberOfSpaces = state.spaceRooms.size) } } is CurrentSpace.Space -> item { @@ -45,10 +41,9 @@ fun HomeSpacesView( avatarData = space.spaceRoom.getAvatarData(AvatarSize.SpaceHeader), name = space.spaceRoom.name, topic = space.spaceRoom.topic, - joinRule = space.spaceRoom.joinRule, + visibility = space.spaceRoom.visibility, heroes = space.spaceRoom.heroes.toImmutableList(), numberOfMembers = space.spaceRoom.numJoinedMembers, - numberOfRooms = space.spaceRoom.childrenCount, ) } } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt index 6da7aadfe7..38d084c7d3 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt @@ -74,7 +74,7 @@ import io.element.android.libraries.designsystem.theme.components.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.theme.placeholderBackground import io.element.android.libraries.matrix.api.core.RoomIdOrAlias -import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility import io.element.android.libraries.matrix.ui.components.SpaceInfoRow import io.element.android.libraries.matrix.ui.components.SpaceMembersView import io.element.android.libraries.matrix.ui.model.InviteSender @@ -567,10 +567,7 @@ private fun DefaultLoadedContent( subtitle = { when { contentState.details is LoadedDetails.Space -> { - SpaceInfoRow( - joinRule = contentState.joinRule ?: JoinRule.Public, - numberOfRooms = contentState.details.childrenCount, - ) + SpaceInfoRow(visibility = SpaceRoomVisibility.fromJoinRule(contentState.joinRule)) } contentState.alias != null -> { RoomPreviewSubtitleAtom(contentState.alias.value) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt index 4f9ec4c561..b165e9d9ca 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt @@ -13,8 +13,10 @@ import io.element.android.features.invite.api.acceptdecline.anAcceptDeclineInvit import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.CurrentUserMembership +import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.previewutils.room.aSpaceRoom +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap import kotlinx.collections.immutable.toImmutableSet @@ -23,6 +25,16 @@ open class SpaceStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aSpaceState(), + aSpaceState( + parentSpace = aSpaceRoom( + joinRule = JoinRule.Public + ) + ), + aSpaceState( + parentSpace = aSpaceRoom( + joinRule = JoinRule.Restricted(persistentListOf()) + ) + ), aSpaceState( parentSpace = aSpaceRoom( rawName = null, diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index 25d4e69b9c..a4615ffc9d 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -134,10 +134,9 @@ private fun SpaceViewContent( avatarData = currentSpace.getAvatarData(AvatarSize.SpaceHeader), name = currentSpace.name, topic = currentSpace.topic, - joinRule = currentSpace.joinRule, + visibility = currentSpace.visibility, heroes = currentSpace.heroes.toImmutableList(), numberOfMembers = currentSpace.numJoinedMembers, - numberOfRooms = currentSpace.childrenCount, ) } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt index c06bbcc723..587cfbcab1 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoom.kt @@ -46,4 +46,6 @@ data class SpaceRoom( } else { rawName } + + val visibility = SpaceRoomVisibility.fromJoinRule(joinRule) } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoomVisibility.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoomVisibility.kt new file mode 100644 index 0000000000..98afa1d508 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceRoomVisibility.kt @@ -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.libraries.matrix.api.spaces + +import androidx.compose.runtime.Immutable +import io.element.android.libraries.matrix.api.room.join.JoinRule +@Immutable +sealed interface SpaceRoomVisibility { + data object Private : SpaceRoomVisibility + data object Public : SpaceRoomVisibility + data object Restricted : SpaceRoomVisibility + + companion object { + fun fromJoinRule(joinRule: JoinRule?): SpaceRoomVisibility = when (joinRule) { + JoinRule.Public -> Public + is JoinRule.Restricted, is JoinRule.KnockRestricted -> Restricted + // Else fallback to Private + else -> Private + } + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt index 22ef102946..9f41171dd9 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt @@ -31,7 +31,6 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun SpaceHeaderRootView( numberOfSpaces: Int, - numberOfRooms: Int, modifier: Modifier = Modifier, ) { Column( @@ -52,7 +51,7 @@ fun SpaceHeaderRootView( ) SpaceInfoRow( leftText = numberOfSpaces(numberOfSpaces), - rightText = numberOfRooms(numberOfRooms), + rightText = null, ) Text( text = stringResource(CommonStrings.screen_space_list_description), @@ -68,6 +67,5 @@ fun SpaceHeaderRootView( internal fun SpaceHeaderRootViewPreview() = ElementPreview { SpaceHeaderRootView( numberOfSpaces = 3, - numberOfRooms = 10, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt index 6dbe7ebf72..e59049f9f2 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt @@ -24,7 +24,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.anAvatarData import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList @@ -38,10 +38,9 @@ fun SpaceHeaderView( avatarData: AvatarData, name: String?, topic: String?, - joinRule: JoinRule?, + visibility: SpaceRoomVisibility, heroes: ImmutableList, numberOfMembers: Int, - numberOfRooms: Int, modifier: Modifier = Modifier, topicMaxLines: Int = Int.MAX_VALUE, ) { @@ -64,12 +63,7 @@ fun SpaceHeaderView( } }, subtitle = { - if (joinRule != null) { - SpaceInfoRow( - joinRule = joinRule, - numberOfRooms = numberOfRooms, - ) - } + SpaceInfoRow(visibility = visibility) }, description = if (topic.isNullOrBlank()) { null @@ -97,7 +91,7 @@ internal fun SpaceHeaderViewPreview() = ElementPreview { name = "Space name", topic = "Space topic: " + LoremIpsum(40).values.first(), topicMaxLines = 2, - joinRule = JoinRule.Public, + visibility = SpaceRoomVisibility.Public, heroes = persistentListOf( aMatrixUser(id = "@1:d", displayName = "Alice", avatarUrl = "aUrl"), aMatrixUser(id = "@2:d", displayName = "Bob"), @@ -105,6 +99,5 @@ internal fun SpaceHeaderViewPreview() = ElementPreview { aMatrixUser(id = "@4:d", displayName = "Dave"), ), numberOfMembers = 999, - numberOfRooms = 10, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceInfoRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceInfoRow.kt index 3d973d97ae..d0d14bcdd4 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceInfoRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceInfoRow.kt @@ -27,14 +27,16 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility +import io.element.android.libraries.matrix.ui.model.icon +import io.element.android.libraries.matrix.ui.model.label import io.element.android.libraries.ui.strings.CommonPlurals import io.element.android.libraries.ui.strings.CommonStrings @Composable fun SpaceInfoRow( leftText: String, - rightText: String, + rightText: String?, modifier: Modifier = Modifier, iconVector: ImageVector? = null, ) { @@ -51,7 +53,11 @@ fun SpaceInfoRow( tint = ElementTheme.colors.iconTertiary, ) } - val text = stringResource(id = CommonStrings.screen_space_list_details, leftText, rightText) + val text = if (rightText != null) { + stringResource(id = CommonStrings.screen_space_list_details, leftText, rightText) + } else { + leftText + } Text( text = text, style = ElementTheme.typography.fontBodyLgRegular, @@ -63,34 +69,14 @@ fun SpaceInfoRow( @Composable fun SpaceInfoRow( - joinRule: JoinRule, - numberOfRooms: Int, + visibility: SpaceRoomVisibility, modifier: Modifier = Modifier, ) { - val (leftText, rightText, icon) = when (joinRule) { - JoinRule.Public -> Triple( - stringResource(id = CommonStrings.common_public_space), - numberOfRooms(numberOfRooms), - CompoundIcons.Public(), - ) - // TODO External space - // JoinRule.Private -> Triple( - // stringResource(id = CommonStrings.common_external_space), - // numberOfRooms(numberOfRooms), - // CompoundIcons.Guest(), - // ) - // JoinRule.Private, - else -> Triple( - stringResource(id = CommonStrings.common_private_space), - numberOfRooms(numberOfRooms), - CompoundIcons.Lock(), - ) - } SpaceInfoRow( - leftText = leftText, - rightText = rightText, + leftText = visibility.label, + rightText = null, modifier = modifier, - iconVector = icon, + iconVector = visibility.icon, ) } @@ -124,12 +110,13 @@ internal fun SpaceInfoRowPreview() = ElementPreview { iconVector = CompoundIcons.Workspace(), ) SpaceInfoRow( - joinRule = JoinRule.Private, - numberOfRooms = 4, + visibility = SpaceRoomVisibility.Private, ) SpaceInfoRow( - joinRule = JoinRule.Public, - numberOfRooms = 10, + visibility = SpaceRoomVisibility.Public + ) + SpaceInfoRow( + visibility = SpaceRoomVisibility.Restricted ) } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt index 1abf0ad95e..2477dd89fd 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceRoomItemView.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom import io.element.android.libraries.designsystem.atomic.molecules.InviteButtonsRowMolecule import io.element.android.libraries.designsystem.components.avatar.Avatar @@ -48,9 +47,11 @@ import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.unreadIndicator import io.element.android.libraries.matrix.api.room.CurrentUserMembership -import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility import io.element.android.libraries.matrix.ui.model.getAvatarData +import io.element.android.libraries.matrix.ui.model.icon +import io.element.android.libraries.matrix.ui.model.label import io.element.android.libraries.ui.strings.CommonPlurals import io.element.android.libraries.ui.strings.CommonStrings @@ -117,8 +118,8 @@ private fun SubtitleRow( if (visibilityIcon != null) { Icon( modifier = Modifier - .size(16.dp) - .padding(end = 4.dp), + .size(16.dp) + .padding(end = 4.dp), imageVector = visibilityIcon, contentDescription = null, tint = ElementTheme.colors.iconTertiary, @@ -176,20 +177,20 @@ private fun SpaceRoomItemScaffold( content: @Composable ColumnScope.() -> Unit, ) { val clickModifier = Modifier - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick, - onLongClickLabel = stringResource(CommonStrings.action_open_context_menu), - indication = ripple(), - interactionSource = remember { MutableInteractionSource() } - ) - .onKeyboardContextMenuAction { onLongClick } + .combinedClickable( + onClick = onClick, + onLongClick = onLongClick, + onLongClickLabel = stringResource(CommonStrings.action_open_context_menu), + indication = ripple(), + interactionSource = remember { MutableInteractionSource() } + ) + .onKeyboardContextMenuAction { onLongClick } Row( modifier = modifier - .fillMaxWidth() - .then(clickModifier) - .padding(horizontal = 16.dp, vertical = 8.dp) - .height(IntrinsicSize.Min), + .fillMaxWidth() + .then(clickModifier) + .padding(horizontal = 16.dp, vertical = 8.dp) + .height(IntrinsicSize.Min), ) { Avatar( avatarData = avatarData, @@ -212,11 +213,7 @@ private fun SpaceRoomItemScaffold( @ReadOnlyComposable private fun SpaceRoom.subtitle(): String { return if (isSpace) { - if (joinRule == JoinRule.Public) { - stringResource(CommonStrings.common_public_space) - } else { - stringResource(CommonStrings.common_private_space) - } + visibility.label } else { pluralStringResource(CommonPlurals.common_member_count, numJoinedMembers, numJoinedMembers) } @@ -226,11 +223,7 @@ private fun SpaceRoom.subtitle(): String { @ReadOnlyComposable private fun SpaceRoom.info(): String { return if (isSpace) { - stringResource( - CommonStrings.screen_space_list_details, - pluralStringResource(CommonPlurals.common_rooms, childrenCount, childrenCount), - pluralStringResource(CommonPlurals.common_member_count, numJoinedMembers, numJoinedMembers), - ) + pluralStringResource(CommonPlurals.common_member_count, numJoinedMembers, numJoinedMembers) } else { topic.orEmpty() } @@ -238,10 +231,11 @@ private fun SpaceRoom.info(): String { @Composable private fun SpaceRoom.visibilityIcon(): ImageVector? { - return if (joinRule == JoinRule.Public) { - CompoundIcons.Public() + // Don't show any icon for restricted rooms as it's the default and would add noise + return if (visibility == SpaceRoomVisibility.Restricted) { + null } else { - CompoundIcons.LockSolid() + visibility.icon } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt index e4b056fdea..779f813aba 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt @@ -7,9 +7,16 @@ package io.element.android.libraries.matrix.ui.model +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility +import io.element.android.libraries.ui.strings.CommonStrings fun SpaceRoom.getAvatarData(size: AvatarSize) = AvatarData( id = roomId.value, @@ -17,3 +24,24 @@ fun SpaceRoom.getAvatarData(size: AvatarSize) = AvatarData( url = avatarUrl, size = size, ) + +val SpaceRoomVisibility.icon: ImageVector + @Composable + get() { + return when (this) { + SpaceRoomVisibility.Private -> CompoundIcons.LockSolid() + SpaceRoomVisibility.Public -> CompoundIcons.Public() + SpaceRoomVisibility.Restricted -> CompoundIcons.Workspace() + } + } + +val SpaceRoomVisibility.label: String + @Composable + @ReadOnlyComposable + get() { + return when (this) { + SpaceRoomVisibility.Private -> stringResource(CommonStrings.common_private_space) + SpaceRoomVisibility.Public -> stringResource(CommonStrings.common_public_space) + SpaceRoomVisibility.Restricted -> stringResource(CommonStrings.common_shared_space) + } + } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 527745898a..9b254127ee 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -94,6 +94,7 @@ "Forgot password?" "Forward" "Go back" + "Go to settings" "Ignore" "Invite" "Invite people" @@ -319,6 +320,7 @@ Reason: %1$s." "Settings" "Share space" "Shared location" + "Shared space" "Signing out" "Something went wrong" "We encountered an issue. Please try again." @@ -427,6 +429,7 @@ Are you sure you want to continue?" "Remove %1$s" "Settings" "Enable thread replies" + "Restarting the app is required to apply changes" "Try out our latest ideas in development. These features are not finalised; they may be unstable, may change." "Feeling experimental?" "Labs" From 199acc4c4d1161952a430d6859d639e1d6a88f24 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 6 Oct 2025 19:21:59 +0000 Subject: [PATCH 62/73] Update screenshots --- .../features.home.impl.spaces_HomeSpacesView_Day_0_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Day_1_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Night_0_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Night_1_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_4_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_4_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_9_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_9_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_0_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_1_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_2_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_3_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_4_en.png | 3 +++ .../images/features.space.impl.root_SpaceView_Day_5_en.png | 3 +++ .../images/features.space.impl.root_SpaceView_Night_0_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Night_1_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Night_2_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Night_3_en.png | 4 ++-- .../images/features.space.impl.root_SpaceView_Night_4_en.png | 3 +++ .../images/features.space.impl.root_SpaceView_Night_5_en.png | 3 +++ ...ries.matrix.ui.components_SpaceHeaderRootView_Day_0_en.png | 4 ++-- ...es.matrix.ui.components_SpaceHeaderRootView_Night_0_en.png | 4 ++-- ...ibraries.matrix.ui.components_SpaceHeaderView_Day_0_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceHeaderView_Night_0_en.png | 4 ++-- .../libraries.matrix.ui.components_SpaceInfoRow_Day_0_en.png | 4 ++-- ...libraries.matrix.ui.components_SpaceInfoRow_Night_0_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_2_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_3_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_4_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_5_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_6_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_7_en.png | 4 ++-- ...raries.matrix.ui.components_SpaceRoomItemView_Day_8_en.png | 3 +++ ...ries.matrix.ui.components_SpaceRoomItemView_Night_2_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_3_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_4_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_5_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_6_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_7_en.png | 4 ++-- ...ries.matrix.ui.components_SpaceRoomItemView_Night_8_en.png | 3 +++ 40 files changed, 86 insertions(+), 68 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_0_en.png index e574e4911e..8d1a8d9b9f 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc1c98131fdad16e22c63feb72536fee912ae84d763c57ff76eaee6d61889b4b -size 127697 +oid sha256:ec84bcc989b8f80e7e025e6d081dfe64165468f3298c3fb5ccd4a75211a4f7bb +size 118364 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_1_en.png index 60ab311cdc..d254ddf882 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a6d3be47ab7d9234657d4d088389c8aadb4d9e073d8c91f4f81dded1b6662a6 -size 42160 +oid sha256:52018347e4361a393b130d1ab479ed96685cacc362b72fd71d46666afef0e6cf +size 40949 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_0_en.png index 41a0545535..6d7c23dadd 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ed12d6dc439b7e7d86580ee24a5cd5c3b5e86b13c4f3cf3e64f677632df5872 -size 124816 +oid sha256:49764c59842a7d3ef7ad9c552bb22e1602c273b0b21f4bc0d9ba79b4942bafe3 +size 116100 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_1_en.png index 2b50f7350b..9a8e074a97 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3f70a15def31e67e84afe7f9545d280bdbca01c6dd63864662f19976df3bf33 -size 40960 +oid sha256:a96b3cd320587af70dd8dee4e285eb374d04ffc2ce8371a3cb07866f514f32f2 +size 39863 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png index 0252e8d778..573d02a807 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd023c99c75dba5987f86951d46e821d378440a35335dc46894ff127951ee50f -size 59135 +oid sha256:cd1294f7077b7d1cf6a048ecd3b51d1bb95fbb34df9c21e332dc0a7c75160ee8 +size 54965 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png index e142b9451b..a2cce20c03 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b9f321dfd59e2a388c0d864c73eca01c29b7f96ee0481597ee3cd8ff1df1781 -size 56262 +oid sha256:e8a8b0b2e6dfae21cf74cbf48f35e4bd52c1951d0ad24fdbb9a7d958b49d68fa +size 52156 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png index cc08744b50..593cc05c7a 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da07e3041ec5814feb0d14e8478d0c817d1496155db2daa612048b94530df20b -size 38200 +oid sha256:7d0bd66c54a98b59a6b4325735eb34ab9bef7c6807c4fc0e33044ee396e46b14 +size 36344 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png index 8af0e7e350..5e4e84c276 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b73e8a2429db6324f471908f46ccd2f6723d59caf4acc738c07d6e402a19285 -size 37752 +oid sha256:029fd9d3e150b6a8d52b4d348ccdbbb661b0009b7065b9530f4e7f168fc6ee78 +size 35965 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_0_en.png index b952647d5d..65b8867270 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bad1ef12ad0fe54c78eb91b56bf6f5528a25fd0e79cfa38976535d97f179dae2 -size 15999 +oid sha256:1251095a4bb43dc672c23b3b3780288f69a4ce26cd5ee249179e94b8a067d3c1 +size 19183 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_1_en.png index 55266468a5..0e81c2bfe6 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1ef7cc669d9e180c220aa6e2d7d69a16be61569c98dbb9e81f41e23d6ecaafd -size 20072 +oid sha256:546ea17f75c5f80282dfa9a021a68eb71e1436b371ff39b399ebe6f7aa5c5121 +size 19216 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_2_en.png index 3b2e097630..a563c82161 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d5111d6ea6b79a4085b65c5d0390d8bbe8d200cc8e50bd9f3cd568ac9ab6179 -size 53740 +oid sha256:7f58e4f6aa72ef41dd5af1e0d309e3909ea1a7d24875135d0d04dd84a3341be8 +size 19572 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_3_en.png index 7b987b6d2c..7bc7c9ebc4 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:377cf0bfc11eb067767b089cc5f35ff92307e3512eb30b6f9d51780acf590f9d -size 52891 +oid sha256:773eb018763a4f19f494043495a60636b5ef1c5fee5c94df7e2e545287725b06 +size 23111 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_4_en.png new file mode 100644 index 0000000000..b92c300ce0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db775b9af1c424150eb5682b3f30df88728a4d28ae598aba1c1a22bf44e5d6b0 +size 52677 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_5_en.png new file mode 100644 index 0000000000..4fc3d6bbdd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd2d09be9476f3ff9cb3710e5bbafc0f493f6afc4f77725cb67e23a7fc6f6e13 +size 51864 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_0_en.png index eb53e9990e..90951be41f 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbe6f27a97a23f24221a89362cd745dedba4ce6de25b93e26117a340b6d565ca -size 15811 +oid sha256:fb27bf8dbb2323da9c7ff2f3a77ed028e76d5b3ec8e2e95991a12feceb074aae +size 18816 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_1_en.png index 66d341ac37..30050d6876 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5798743a5ee59f6842297439ce338652225d8aa18aebebd3aa1785f06fa4863 -size 19723 +oid sha256:e354f7346a10f75679427774ff96e9b13129b76c8b98944ad4e89b482b110a51 +size 18868 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_2_en.png index f018c0a4a5..b859185d49 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75d18c001040426b961c5f7d0115a2dbad7e3cd1eb8a7af09357cdda1cc591a4 -size 52470 +oid sha256:d80cd45594d19ecf6e7bf103bb374dd86013bd05e7c10cd3df31e66c2b2cda01 +size 19223 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_3_en.png index dab60e5012..385d518b02 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26e17ed257ded386bf0538c68f6848841f28d4ffd04a8d3f7d3b41feb203deb2 -size 51517 +oid sha256:7266aeb27353112291ef11d80732eae25ae5c936404af13a99c4572d30bae6a0 +size 22670 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_4_en.png new file mode 100644 index 0000000000..150431b180 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6701688f5a1b8e59f42bc6e429a561a120576c5d119a3df123d4ee5fc1acb887 +size 51384 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_5_en.png new file mode 100644 index 0000000000..13c3fcb7ce --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.root_SpaceView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b51e599bbad12e70b116680b00cdd376c921769dbc7b2f918ba9a0919a88847 +size 50509 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en.png index 03b2c21087..4c16bb72ca 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fec2a25db38f9c65e3fd0218fc5c9937a017b762696dfd7be2906c7cbc28336 -size 19111 +oid sha256:a4e7d8316854658fca2e0edfc22bd844a7972543d0049cd751de31767ee1cc2d +size 17325 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en.png index a4dc748f4f..b17f53e338 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5412ef6dc7306f203649b777cb43ce0ef011e65640e84f14b12dd3198f68b992 -size 18204 +oid sha256:8952a3e1251c854f7b59990ca41cdb11c2ee0f36545e20237057591b5d5cfc58 +size 16481 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Day_0_en.png index 7a7bf57ab7..7bf24eff1b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21acaf9ea606378f5f1e83795e41bec9edc2da05143efba04b70f67cce2c80b0 -size 61626 +oid sha256:7bfe638b75f253649e2d591bf174c9afa176c400e8826ba30f7e1eb50ad9b69e +size 60450 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Night_0_en.png index e76102c580..78271cc12e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceHeaderView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e20d4dc80e8f983516cde0361333f941818cade431fb38ae318cfa9a589ab0d8 -size 60846 +oid sha256:f958cae6847bb68aa751cb79d3ceb0c2ea6d112f21a60d8c19633e7008a0e724 +size 59606 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Day_0_en.png index 7138e2aa39..c5c9ae1eda 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e4684cfbe7611d6c68879ddd7da5c57aa542b9f8b9250caf5f27009cabaadb2 -size 22353 +oid sha256:b20135fb6973d9d435fe1bfebb654d23ff2e1487b3863387c0843a5df63a6d28 +size 22858 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Night_0_en.png index 38e9551bc3..59647a9419 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceInfoRow_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c7ad1861890262a67664d4e3b3e28d8a5d9ac4556ad029d1d5a387f61ac513f -size 21275 +oid sha256:3ea661953786398d16100c2209c7549f0dd0798f452947b7f74204319fa4e799 +size 21626 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en.png index b90c8c5ba1..a6d7438f74 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f6b5eaa4a84fc70cab57d37737b390583d3af9f6e829cecffbcf36351bd40e2 -size 23562 +oid sha256:0145025b77b028a27a4f3dfc9e14a42faa26c55e056464f4b93b2513b16a699d +size 9027 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en.png index eeafaa0dab..b90c8c5ba1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f271f630d93fdf49436509d08276b6a444db92c06fd06129af93cffbb4623d4 -size 17931 +oid sha256:9f6b5eaa4a84fc70cab57d37737b390583d3af9f6e829cecffbcf36351bd40e2 +size 23562 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en.png index f925a8d461..eeafaa0dab 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9fed82716640b4c96b6ef666d9f992e966c17ebddc275c5f562b412e2d549b0 -size 15065 +oid sha256:0f271f630d93fdf49436509d08276b6a444db92c06fd06129af93cffbb4623d4 +size 17931 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en.png index 8ea41b3e64..450015669c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79e7cecc4b03937d2a030721383664d54466e7ce25459c3628ace8b36b305214 -size 35293 +oid sha256:3a35bc50a8834997cf3bfd3884e82297e4f27d95462e23997e1887e8bf782c59 +size 13535 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en.png index 7b1b324268..770acda2a0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7798eeef4a1de3312ec69b757963c6430d3952d45db6346961f79dae4e15913a -size 41389 +oid sha256:ad1cdaac2d2f1e42e3ca1b17c88b7c9a2ead134a7004885a3c3b3dcd41b13ce5 +size 33645 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en.png index 7b1b324268..fbc692ffd1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7798eeef4a1de3312ec69b757963c6430d3952d45db6346961f79dae4e15913a -size 41389 +oid sha256:ef19b16146a20517f04e4fa516b2d48af8cacfb5d6f69aacc308656a883765be +size 39808 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en.png new file mode 100644 index 0000000000..fbc692ffd1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef19b16146a20517f04e4fa516b2d48af8cacfb5d6f69aacc308656a883765be +size 39808 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en.png index 5085864cc6..8ea8a0dbe0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:690df48431acad687f2a2e72aebba4fa63de433ed68b7b9e19818a78973cd211 -size 22676 +oid sha256:f8454b2a9f7959ff981b5fee1b49926d3e22f7255ebadaa15731e494d2416d4c +size 8930 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en.png index 1e85e954f6..5085864cc6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34073398379389aa862c892e6eaa33574606071597a0095dfa5c84b99154b5df -size 17218 +oid sha256:690df48431acad687f2a2e72aebba4fa63de433ed68b7b9e19818a78973cd211 +size 22676 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en.png index 45f9f23c79..1e85e954f6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13d555688a963f8bf664c8bafc397a48c31575d4a2c2fa06a20b191e620d23ea -size 14587 +oid sha256:34073398379389aa862c892e6eaa33574606071597a0095dfa5c84b99154b5df +size 17218 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en.png index 4c0e5e6671..252a083540 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac86fef06b52c5456c5eb828c1b60615792906f74d15ea35e3289d2cff47ee1 -size 34183 +oid sha256:1dcdb9795595067c90efd2c3e3d34d740b5c1ed5e02d487c7e03f10f9653c3a7 +size 13134 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en.png index d2f9e318e8..73e31905c7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b431eae85dcb3e5efde883a47c78aab6c346429366357bb5f6e740342eeeb97 -size 40072 +oid sha256:cef17e2d54dd9c8eacb9e7d3206fabf9acc91f1d4192bd9e13da0d9356eb536b +size 32669 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en.png index d2f9e318e8..bf4eb4d4de 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b431eae85dcb3e5efde883a47c78aab6c346429366357bb5f6e740342eeeb97 -size 40072 +oid sha256:46fe78468ca13402a6cc78f2420ba72b8c5fe13a442e4e424c68eb74362acccb +size 38488 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en.png new file mode 100644 index 0000000000..bf4eb4d4de --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46fe78468ca13402a6cc78f2420ba72b8c5fe13a442e4e424c68eb74362acccb +size 38488 From adb4828da41b946dc33e775812af1ae73b1f15b2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 7 Oct 2025 10:24:48 +0200 Subject: [PATCH 63/73] feature(space): fix space tests compilation --- .../features/space/impl/leave/LeaveSpacePresenterTest.kt | 4 ++-- .../element/android/features/space/impl/root/SpaceViewTest.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt index 5bdd100c93..7c3336e0fe 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt @@ -29,7 +29,7 @@ import org.junit.Test class LeaveSpacePresenterTest { private val aSpace = aSpaceRoom( roomId = A_SPACE_ID, - name = A_SPACE_NAME, + rawName = A_SPACE_NAME, ) @Test @@ -198,7 +198,7 @@ class LeaveSpacePresenterTest { private fun aLeaveSpaceRoom( spaceRoom: SpaceRoom = aSpaceRoom( roomId = A_SPACE_ID, - name = A_SPACE_NAME, + rawName = A_SPACE_NAME, ), isLastAdmin: Boolean = false, ) = LeaveSpaceRoom( diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt index f95b4e6514..9e0897cb8f 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt @@ -52,7 +52,7 @@ class SpaceViewTest { @Test fun `clicking on a room name invokes the expected callback`() { - val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, name = A_ROOM_NAME) + val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, rawName = A_ROOM_NAME) val eventsRecorder = EventsRecorder(expectEvents = false) ensureCalledOnceWithParam(aSpaceRoom) { rule.setSpaceView( From 9714abe032e70c7cc84bb50ed192f434fe0dd37d Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 7 Oct 2025 12:02:54 +0200 Subject: [PATCH 64/73] Add Labs screen for beta testing of public features (#5465) * Add Labs screen: - Make `Feature` have an `isInLabs` boolean to distinguish private feature flags from public ones. - Have `FeatureFlagsService` provide the list of available flags. - Display the labs item in the settings screen only if there are available public features. - Remove public feature toggles from developer options. - Implement the labs screen with the public features. - Add a clear cache step to the threads feature toggle - Update screenshots --------- Co-authored-by: ElementBot --- .../preferences/impl/PreferencesFlowNode.kt | 11 ++ .../developer/DeveloperSettingsPresenter.kt | 5 +- .../preferences/impl/labs/LabsEvents.kt | 14 ++ .../preferences/impl/labs/LabsNode.kt | 32 +++++ .../preferences/impl/labs/LabsPresenter.kt | 124 +++++++++++++++++ .../preferences/impl/labs/LabsState.kt | 17 +++ .../impl/labs/LabsStateProvider.kt | 48 +++++++ .../preferences/impl/labs/LabsView.kt | 107 +++++++++++++++ .../impl/root/PreferencesRootNode.kt | 6 + .../impl/root/PreferencesRootPresenter.kt | 3 + .../impl/root/PreferencesRootState.kt | 1 + .../impl/root/PreferencesRootStateProvider.kt | 1 + .../impl/root/PreferencesRootView.kt | 13 ++ .../impl/src/main/res/values/localazy.xml | 5 + .../DeveloperSettingsPresenterTest.kt | 60 ++++++++- .../impl/labs/LabsPresenterTest.kt | 126 ++++++++++++++++++ .../impl/root/PreferencesRootPresenterTest.kt | 47 +++++++ .../libraries/featureflag/api/Feature.kt | 6 + .../featureflag/api/FeatureFlagService.kt | 5 + .../libraries/featureflag/api/FeatureFlags.kt | 2 + .../impl/DefaultFeatureFlagService.kt | 5 + .../libraries/featureflag/test/FakeFeature.kt | 20 +++ .../test/FakeFeatureFlagService.kt | 5 + .../featureflag/ui/model/FeatureUiModel.kt | 3 + .../ui/model/FeatureUiModelProvider.kt | 4 +- ...references.impl.labs_LabsView_Day_0_en.png | 3 + ...references.impl.labs_LabsView_Day_1_en.png | 3 + ...ferences.impl.labs_LabsView_Night_0_en.png | 3 + ...ferences.impl.labs_LabsView_Night_1_en.png | 3 + ...impl.root_PreferencesRootViewDark_0_en.png | 4 +- ...impl.root_PreferencesRootViewDark_1_en.png | 4 +- ...mpl.root_PreferencesRootViewLight_0_en.png | 4 +- ...mpl.root_PreferencesRootViewLight_1_en.png | 4 +- tools/localazy/config.json | 3 +- 34 files changed, 684 insertions(+), 17 deletions(-) create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsEvents.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenter.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsState.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsStateProvider.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsView.kt create mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenterTest.kt create mode 100644 libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeature.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index c9ae2862c1..e4ba87c43a 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -30,6 +30,7 @@ import io.element.android.features.preferences.impl.advanced.AdvancedSettingsNod import io.element.android.features.preferences.impl.analytics.AnalyticsSettingsNode import io.element.android.features.preferences.impl.blockedusers.BlockedUsersNode import io.element.android.features.preferences.impl.developer.DeveloperSettingsNode +import io.element.android.features.preferences.impl.labs.LabsNode import io.element.android.features.preferences.impl.notifications.NotificationSettingsNode import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingNode import io.element.android.features.preferences.impl.root.PreferencesRootNode @@ -75,6 +76,9 @@ class PreferencesFlowNode( @Parcelize data object AdvancedSettings : NavTarget + @Parcelize + data object Labs : NavTarget + @Parcelize data object AnalyticsSettings : NavTarget @@ -152,6 +156,10 @@ class PreferencesFlowNode( backstack.push(NavTarget.AdvancedSettings) } + override fun onOpenLabs() { + backstack.push(NavTarget.Labs) + } + override fun onOpenUserProfile(matrixUser: MatrixUser) { backstack.push(NavTarget.UserProfile(matrixUser)) } @@ -178,6 +186,9 @@ class PreferencesFlowNode( } createNode(buildContext, listOf(developerSettingsCallback)) } + NavTarget.Labs -> { + createNode(buildContext) + } NavTarget.About -> { val callback = object : AboutNode.Callback { override fun openOssLicenses() { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index e07c30bac9..034aee12d3 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -90,8 +90,8 @@ class DeveloperSettingsPresenter( } LaunchedEffect(Unit) { - FeatureFlags.entries - .filter { it.isFinished.not() } + featureFlagService.getAvailableFeatures() + .filter { it.isInLabs.not() && it.isFinished.not() } .run { // Never display room directory search in release builds for Play Store if (buildMeta.flavorDescription == "GooglePlay" && buildMeta.buildType == BuildType.RELEASE) { @@ -169,6 +169,7 @@ class DeveloperSettingsPresenter( key = feature.key, title = feature.title, description = feature.description, + icon = null, isEnabled = isEnabled ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsEvents.kt new file mode 100644 index 0000000000..0f652a5c5c --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsEvents.kt @@ -0,0 +1,14 @@ +/* + * 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.preferences.impl.labs + +import io.element.android.libraries.featureflag.ui.model.FeatureUiModel + +sealed interface LabsEvents { + data class ToggleFeature(val feature: FeatureUiModel) : LabsEvents +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt new file mode 100644 index 0000000000..5c2b5ed0e3 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt @@ -0,0 +1,32 @@ +/* + * 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.preferences.impl.labs + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class LabsNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: LabsPresenter, +) : Node(buildContext, plugins = plugins) { + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + LabsView(state = state, onBack = ::navigateUp) + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenter.kt new file mode 100644 index 0000000000..5e74454d75 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenter.kt @@ -0,0 +1,124 @@ +/* + * 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.preferences.impl.labs + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.key +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshots.SnapshotStateMap +import dev.zacsweers.metro.Inject +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.preferences.impl.R +import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.bool.orFalse +import io.element.android.libraries.designsystem.theme.components.IconSource +import io.element.android.libraries.featureflag.api.Feature +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.ui.model.FeatureUiModel +import io.element.android.services.toolbox.api.strings.StringProvider +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.launch + +@Inject +class LabsPresenter( + private val stringProvider: StringProvider, + private val featureFlagService: FeatureFlagService, + private val clearCacheUseCase: ClearCacheUseCase, +) : Presenter { + @Composable + override fun present(): LabsState { + val coroutineScope = rememberCoroutineScope() + val features = remember { + val entries = featureFlagService.getAvailableFeatures() + .filter { it.isInLabs && !it.isFinished } + .map { it.key to it } + mutableStateMapOf(*entries.toTypedArray()) + } + val enabledFeatures = remember { + mutableStateMapOf() + } + + LaunchedEffect(Unit) { + for (feature in features.values) { + val isEnabled = featureFlagService.isFeatureEnabled(feature) + enabledFeatures[feature.key] = isEnabled + } + } + + var isApplyingChanges by remember { mutableStateOf(false) } + + val featureUiModels = createUiModels(features, enabledFeatures) + + fun handleEvent(event: LabsEvents) { + when (event) { + is LabsEvents.ToggleFeature -> coroutineScope.launch { + val feature = features[event.feature.key] ?: return@launch + val isEnabled = featureFlagService.isFeatureEnabled(feature) + featureFlagService.setFeatureEnabled(feature = feature, enabled = !isEnabled) + enabledFeatures[feature.key] = !isEnabled + + when (feature.key) { + FeatureFlags.Threads.key -> { + // Threads require a cache clear to recreate the event cache + clearCacheUseCase() + isApplyingChanges = true + } + } + } + } + } + + return LabsState( + features = featureUiModels, + isApplyingChanges = isApplyingChanges, + eventSink = ::handleEvent, + ) + } + + @Composable + private fun createUiModels( + features: SnapshotStateMap, + enabledFeatures: SnapshotStateMap + ): ImmutableList { + return features.values.map { feature -> + key(feature.key) { + val isEnabled = enabledFeatures[feature.key].orFalse() + val title = when (feature) { + FeatureFlags.Threads -> stringProvider.getString(R.string.screen_labs_enable_threads) + else -> feature.title + } + val description = when (feature) { + FeatureFlags.Threads -> stringProvider.getString(R.string.screen_labs_enable_threads_description) + else -> feature.description + } + val icon = when (feature) { + FeatureFlags.Threads -> CompoundIcons.Threads() + else -> null + } + remember(feature, isEnabled) { + FeatureUiModel( + key = feature.key, + title = title, + description = description, + icon = icon?.let(IconSource::Vector), + isEnabled = isEnabled + ) + } + } + }.toImmutableList() + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsState.kt new file mode 100644 index 0000000000..0925cd7893 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsState.kt @@ -0,0 +1,17 @@ +/* + * 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.preferences.impl.labs + +import io.element.android.libraries.featureflag.ui.model.FeatureUiModel +import kotlinx.collections.immutable.ImmutableList + +data class LabsState( + val features: ImmutableList, + val isApplyingChanges: Boolean, + val eventSink: (LabsEvents) -> Unit, +) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsStateProvider.kt new file mode 100644 index 0000000000..df804cd409 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsStateProvider.kt @@ -0,0 +1,48 @@ +/* + * 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.preferences.impl.labs + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.designsystem.icons.CompoundDrawables +import io.element.android.libraries.designsystem.theme.components.IconSource +import io.element.android.libraries.featureflag.ui.model.FeatureUiModel +import kotlinx.collections.immutable.toImmutableList + +internal class LabsStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aLabsState(features = aFeatureList()), + aLabsState(features = aFeatureList(), isApplyingChanges = true), + ) +} + +internal fun aLabsState( + features: List = emptyList(), + isApplyingChanges: Boolean = false, +) = LabsState( + features = features.toImmutableList(), + isApplyingChanges = isApplyingChanges, + eventSink = {}, +) + +internal fun aFeatureList() = listOf( + FeatureUiModel( + key = "feature_1", + title = "Feature 1", + description = "This is a description of feature 1.", + isEnabled = true, + icon = IconSource.Resource(CompoundDrawables.ic_compound_threads), + ), + FeatureUiModel( + key = "feature_2", + title = "Feature 2", + description = "This is a description of feature 2.", + isEnabled = false, + icon = IconSource.Resource(CompoundDrawables.ic_compound_video_call), + ) +) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsView.kt new file mode 100644 index 0000000000..2738da4b63 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsView.kt @@ -0,0 +1,107 @@ +/* + * 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.preferences.impl.labs + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.preferences.impl.R +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.list.ListItemContent +import io.element.android.libraries.designsystem.components.list.SwitchListItem +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.TopAppBar + +/** + * The contents of the Labs screen. + * Design: https://www.figma.com/design/V0dkfRAW6T3yCQKjahpzkX/ER-46-EX--Threads?node-id=2004-27319&t=yssy1yYYigsGON3s-0 + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LabsView( + state: LabsState, + onBack: () -> Unit, + modifier: Modifier = Modifier, +) { + if (state.isApplyingChanges) { + ProgressDialog() + } + + BackHandler( + enabled = !state.isApplyingChanges, + onBack = onBack, + ) + + HeaderFooterPage( + modifier = modifier + .fillMaxSize() + .systemBarsPadding() + .imePadding(), + topBar = { + TopAppBar( + titleStr = stringResource(R.string.screen_labs_title), + navigationIcon = { + BackButton(onClick = onBack, enabled = !state.isApplyingChanges) + } + ) + }, + header = { + IconTitleSubtitleMolecule( + modifier = Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp), + title = stringResource(R.string.screen_labs_header_title), + subTitle = stringResource(R.string.screen_labs_header_description), + iconStyle = BigIcon.Style.Default(CompoundIcons.Labs()) + ) + }, + contentPadding = PaddingValues(), + content = { + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(horizontal = 10.dp, vertical = 20.dp), + ) { + items(items = state.features, key = { it.key }) { feature -> + SwitchListItem( + leadingContent = feature.icon?.let { ListItemContent.Icon(it) }, + headline = feature.title, + supportingText = feature.description, + value = feature.isEnabled, + onChange = { + state.eventSink(LabsEvents.ToggleFeature(feature)) + } + ) + } + } + } + ) +} + +@PreviewsDayNight +@Composable +internal fun LabsViewPreview(@PreviewParameter(LabsStateProvider::class) state: LabsState) { + ElementPreview { + LabsView(state = state, onBack = {}) + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt index 1bb322108f..67d50a76f0 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt @@ -43,6 +43,7 @@ class PreferencesRootNode( fun onOpenNotificationSettings() fun onOpenLockScreenSettings() fun onOpenAdvancedSettings() + fun onOpenLabs() fun onOpenUserProfile(matrixUser: MatrixUser) fun onOpenBlockedUsers() fun onSignOutClick() @@ -69,6 +70,10 @@ class PreferencesRootNode( plugins().forEach { it.onOpenAdvancedSettings() } } + private fun onOpenLabs() { + plugins().forEach { it.onOpenLabs() } + } + private fun onOpenAnalytics() { plugins().forEach { it.onOpenAnalytics() } } @@ -131,6 +136,7 @@ class PreferencesRootNode( onSecureBackupClick = this::onSecureBackupClick, onOpenDeveloperSettings = this::onOpenDeveloperSettings, onOpenAdvancedSettings = this::onOpenAdvancedSettings, + onOpenLabs = this::onOpenLabs, onManageAccountClick = { onManageAccountClick(activity, it, isDark) }, onOpenNotificationSettings = this::onOpenNotificationSettings, onOpenLockScreenSettings = this::onOpenLockScreenSettings, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt index ebb9a5a867..be18a2daa2 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt @@ -112,6 +112,8 @@ class PreferencesRootPresenter( .launchIn(this) } + val showLabsItem = remember { featureFlagService.getAvailableFeatures().any { it.isInLabs && !it.isFinished } } + val directLogoutState = directLogoutPresenter.present() LaunchedEffect(Unit) { @@ -146,6 +148,7 @@ class PreferencesRootPresenter( showDeveloperSettings = showDeveloperSettings, canDeactivateAccount = canDeactivateAccount, showBlockedUsersItem = showBlockedUsersItem, + showLabsItem = showLabsItem, directLogoutState = directLogoutState, snackbarMessage = snackbarMessage, eventSink = ::handleEvent, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt index 830c397c59..3df13e0efd 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt @@ -28,6 +28,7 @@ data class PreferencesRootState( val showDeveloperSettings: Boolean, val canDeactivateAccount: Boolean, val showBlockedUsersItem: Boolean, + val showLabsItem: Boolean, val directLogoutState: DirectLogoutState, val snackbarMessage: SnackbarMessage?, val eventSink: (PreferencesRootEvents) -> Unit, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt index 604cb10c4d..5a7efc6926 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt @@ -33,6 +33,7 @@ fun aPreferencesRootState( canReportBug = true, showDeveloperSettings = true, showBlockedUsersItem = true, + showLabsItem = true, canDeactivateAccount = true, snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete), directLogoutState = aDirectLogoutState(), diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 56aa4bb126..3b4d2d2670 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -59,6 +59,7 @@ fun PreferencesRootView( onOpenAbout: () -> Unit, onOpenDeveloperSettings: () -> Unit, onOpenAdvancedSettings: () -> Unit, + onOpenLabs: () -> Unit, onOpenNotificationSettings: () -> Unit, onOpenUserProfile: (MatrixUser) -> Unit, onOpenBlockedUsers: () -> Unit, @@ -110,6 +111,7 @@ fun PreferencesRootView( onOpenRageShake = onOpenRageShake, onOpenAdvancedSettings = onOpenAdvancedSettings, onOpenDeveloperSettings = onOpenDeveloperSettings, + onOpenLabs = onOpenLabs, onSignOutClick = onSignOutClick, onDeactivateClick = onDeactivateClick, ) @@ -230,6 +232,7 @@ private fun ColumnScope.GeneralSection( onOpenAnalytics: () -> Unit, onOpenRageShake: () -> Unit, onOpenAdvancedSettings: () -> Unit, + onOpenLabs: () -> Unit, onOpenDeveloperSettings: () -> Unit, onSignOutClick: () -> Unit, onDeactivateClick: () -> Unit, @@ -258,6 +261,15 @@ private fun ColumnScope.GeneralSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Settings())), onClick = onOpenAdvancedSettings, ) + + if (state.showLabsItem) { + ListItem( + headlineContent = { Text(stringResource(id = R.string.screen_labs_title)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Labs())), + onClick = onOpenLabs, + ) + } + ListItem( headlineContent = { Text(stringResource(id = CommonStrings.action_signout)) }, leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.SignOut())), @@ -336,6 +348,7 @@ private fun ContentToPreview(matrixUser: MatrixUser) { onOpenRageShake = {}, onOpenDeveloperSettings = {}, onOpenAdvancedSettings = {}, + onOpenLabs = {}, onOpenAbout = {}, onSecureBackupClick = {}, onManageAccountClick = {}, diff --git a/features/preferences/impl/src/main/res/values/localazy.xml b/features/preferences/impl/src/main/res/values/localazy.xml index 89c5ffba85..31ee676226 100644 --- a/features/preferences/impl/src/main/res/values/localazy.xml +++ b/features/preferences/impl/src/main/res/values/localazy.xml @@ -44,6 +44,11 @@ "Unable to update profile" "Edit profile" "Updating profile…" + "Enable thread replies" + "The app will restart to apply this change." + "Try out our latest ideas in development. These features are not finalised; they may be unstable, may change." + "Feeling experimental?" + "Labs" "Additional settings" "Audio and video calls" "Configuration mismatch" diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index 9e2c8ca175..76b22871f0 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -19,6 +19,7 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore @@ -35,7 +36,16 @@ class DeveloperSettingsPresenterTest { @Test fun `present - ensures initial states are correct`() = runTest { - val presenter = createDeveloperSettingsPresenter() + val availableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = false, + ) + ) + val presenter = createDeveloperSettingsPresenter( + featureFlagService = FakeFeatureFlagService(providedAvailableFeatures = availableFeatures) + ) presenter.test { awaitItem().also { state -> assertThat(state.features).isEmpty() @@ -50,8 +60,7 @@ class DeveloperSettingsPresenterTest { } awaitItem().also { state -> assertThat(state.features).isNotEmpty() - val numberOfModifiableFeatureFlags = FeatureFlags.entries.count { it.isFinished.not() } - assertThat(state.features).hasSize(numberOfModifiableFeatureFlags) + assertThat(state.features).hasSize(1) assertThat(state.tracingLogLevel.dataOrNull()).isEqualTo(LogLevelItem.INFO) } awaitItem().also { state -> @@ -161,8 +170,51 @@ class DeveloperSettingsPresenterTest { } } + @Test + fun `present - won't display features in labs or finished`() = runTest { + val availableFeatures = listOf( + // Only this feature should be displayed + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = false, + ), + FakeFeature( + key = "feature_2", + title = "Feature 2", + isInLabs = true, + ), + FakeFeature( + key = "feature_3", + title = "Feature 3", + isInLabs = false, + isFinished = true, + ) + ) + + val presenter = createDeveloperSettingsPresenter( + featureFlagService = FakeFeatureFlagService( + providedAvailableFeatures = availableFeatures, + ) + ) + presenter.test { + skipItems(2) + awaitItem().also { state -> + assertThat(state.features).hasSize(1) + } + } + } + private fun createDeveloperSettingsPresenter( - featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService(), + featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService( + providedAvailableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = false, + ) + ) + ), cacheSizeUseCase: FakeComputeCacheSizeUseCase = FakeComputeCacheSizeUseCase(), clearCacheUseCase: FakeClearCacheUseCase = FakeClearCacheUseCase(), preferencesStore: InMemoryAppPreferencesStore = InMemoryAppPreferencesStore(), diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenterTest.kt new file mode 100644 index 0000000000..5117a9fe94 --- /dev/null +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/labs/LabsPresenterTest.kt @@ -0,0 +1,126 @@ +/* + * 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.preferences.impl.labs + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase +import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase +import io.element.android.libraries.featureflag.api.Feature +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeature +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.services.toolbox.test.strings.FakeStringProvider +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class LabsPresenterTest { + @Test + fun `present - ensures only unfinished features in labs are displayed`() = runTest { + val availableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = true, + ), + FakeFeature( + key = "feature_2", + title = "Feature 2", + isInLabs = false, + ), + FakeFeature( + key = "feature_3", + title = "Feature 3", + isInLabs = true, + isFinished = true, + ) + ) + createLabsPresenter( + availableFeatures = availableFeatures, + ).test { + val receivedFeatures = awaitItem().features + assertThat(receivedFeatures).hasSize(1) + assertThat(receivedFeatures.first().key).isEqualTo(availableFeatures.first().key) + + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - ToggleFeature actually toggles the value`() = runTest { + val availableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = true, + ), + ) + createLabsPresenter( + availableFeatures = availableFeatures, + ).test { + val initialItem = awaitItem() + val feature = initialItem.features.first() + assertThat(feature.isEnabled).isFalse() + + // Wait until the data finished loading + skipItems(1) + + // Toggle the feature, should be true now + initialItem.eventSink(LabsEvents.ToggleFeature(feature)) + assertThat(awaitItem().features.first().isEnabled).isTrue() + + // Toggle the feature, should be false now + initialItem.eventSink(LabsEvents.ToggleFeature(feature)) + assertThat(awaitItem().features.first().isEnabled).isFalse() + } + } + + @Test + fun `present - ToggleFeature with the 'Threads' feature resets the cache`() = runTest { + val availableFeatures = listOf( + FakeFeature( + key = FeatureFlags.Threads.key, + title = "Threads", + isInLabs = true, + ), + ) + + val clearCacheUseCase = FakeClearCacheUseCase() + createLabsPresenter( + availableFeatures = availableFeatures, + clearCacheUseCase = clearCacheUseCase, + ).test { + val initialItem = awaitItem() + val feature = initialItem.features.first() + assertThat(feature.isEnabled).isFalse() + assertThat(initialItem.isApplyingChanges).isFalse() + + // Wait until the data finished loading + skipItems(1) + + // Toggle the feature + initialItem.eventSink(LabsEvents.ToggleFeature(feature)) + assertThat(awaitItem().features.first().isEnabled).isTrue() + + // The clear cache use case should have been called + assertThat(awaitItem().isApplyingChanges).isTrue() + assertThat(clearCacheUseCase.executeHasBeenCalled).isTrue() + } + } + + private fun createLabsPresenter( + availableFeatures: List = emptyList(), + clearCacheUseCase: ClearCacheUseCase = FakeClearCacheUseCase(), + ): LabsPresenter { + return LabsPresenter( + stringProvider = FakeStringProvider(), + featureFlagService = FakeFeatureFlagService(providedAvailableFeatures = availableFeatures), + clearCacheUseCase = clearCacheUseCase, + ) + } +} diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt index 0f6eec3c6d..f65589beb6 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.test.FakeIndicatorService @@ -184,6 +185,52 @@ class PreferencesRootPresenterTest { } } + @Test + fun `present - labs can be shown if any feature flag is in labs and not finished`() = runTest { + createPresenter( + featureFlagService = FakeFeatureFlagService( + providedAvailableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = true, + isFinished = false, + ) + ) + ), + matrixClient = FakeMatrixClient( + canDeactivateAccountResult = { true }, + accountManagementUrlResult = { Result.success(null) }, + ), + ).test { + assertThat(awaitItem().showLabsItem).isTrue() + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - labs can't be shown if all feature flags in labs are finished`() = runTest { + createPresenter( + featureFlagService = FakeFeatureFlagService( + providedAvailableFeatures = listOf( + FakeFeature( + key = "feature_1", + title = "Feature 1", + isInLabs = true, + isFinished = true, + ) + ) + ), + matrixClient = FakeMatrixClient( + canDeactivateAccountResult = { true }, + accountManagementUrlResult = { Result.success(null) }, + ), + ).test { + assertThat(awaitItem().showLabsItem).isFalse() + cancelAndIgnoreRemainingEvents() + } + } + @Test fun `present - multiple accounts`() = runTest { createPresenter( diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/Feature.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/Feature.kt index af1031450e..18a9ea1bc3 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/Feature.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/Feature.kt @@ -36,4 +36,10 @@ interface Feature { * If true: the feature is finished, it will not appear in the developer options screen. */ val isFinished: Boolean + + /** + * Whether the feature is only available in Labs (and not in developer options). + * Feature flags that set this to `true` can be enabled by any users, not only those that have enabled developer mode. + */ + val isInLabs: Boolean } diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt index 3bd94c9bd7..1358909771 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlagService.kt @@ -33,4 +33,9 @@ interface FeatureFlagService { * is registered */ suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean): Boolean + + /** + * @return the list of available (not finished) features that can be toggled. + */ + fun getAvailableFeatures(): List } diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index a7c4113b62..cb908dbe5e 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -19,6 +19,7 @@ enum class FeatureFlags( override val description: String? = null, override val defaultValue: (BuildMeta) -> Boolean, override val isFinished: Boolean, + override val isInLabs: Boolean = false, ) : Feature { RoomDirectorySearch( key = "feature.roomdirectorysearch", @@ -98,6 +99,7 @@ enum class FeatureFlags( description = "Renders thread messages as a dedicated timeline. Restarting the app is required for this setting to fully take effect.", defaultValue = { false }, isFinished = false, + isInLabs = true, ), MultiAccount( key = "feature.multi_account", diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt index 5bcbe93085..01c1e8a258 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt @@ -14,6 +14,7 @@ import dev.zacsweers.metro.SingleIn import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.featureflag.api.Feature import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @@ -40,4 +41,8 @@ class DefaultFeatureFlagService( ?.let { true } ?: false } + + override fun getAvailableFeatures(): List { + return FeatureFlags.entries.filter { !it.isFinished } + } } diff --git a/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeature.kt b/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeature.kt new file mode 100644 index 0000000000..a141fbdd75 --- /dev/null +++ b/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeature.kt @@ -0,0 +1,20 @@ +/* + * 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.libraries.featureflag.test + +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.featureflag.api.Feature + +data class FakeFeature( + override val key: String, + override val title: String, + override val description: String? = null, + override val defaultValue: (BuildMeta) -> Boolean = { false }, + override val isFinished: Boolean = false, + override val isInLabs: Boolean = false, +) : Feature diff --git a/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeatureFlagService.kt b/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeatureFlagService.kt index 695d3014bc..49fc095ed4 100644 --- a/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeatureFlagService.kt +++ b/libraries/featureflag/test/src/main/java/io/element/android/libraries/featureflag/test/FakeFeatureFlagService.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.MutableStateFlow class FakeFeatureFlagService( initialState: Map = emptyMap(), private val buildMeta: BuildMeta = aBuildMeta(), + var providedAvailableFeatures: List = emptyList(), ) : FeatureFlagService { private val enabledFeatures = initialState .mapValues { MutableStateFlow(it.value) } @@ -31,4 +32,8 @@ class FakeFeatureFlagService( override fun isFeatureEnabledFlow(feature: Feature): Flow { return enabledFeatures.getOrPut(feature.key) { MutableStateFlow(feature.defaultValue(buildMeta)) } } + + override fun getAvailableFeatures(): List { + return providedAvailableFeatures + } } diff --git a/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModel.kt b/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModel.kt index d6fa020f2f..f37e096c5b 100644 --- a/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModel.kt +++ b/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModel.kt @@ -7,9 +7,12 @@ package io.element.android.libraries.featureflag.ui.model +import io.element.android.libraries.designsystem.theme.components.IconSource + data class FeatureUiModel( val key: String, val title: String, val description: String?, + val icon: IconSource?, val isEnabled: Boolean ) diff --git a/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModelProvider.kt b/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModelProvider.kt index 4d515eb984..66697b447f 100644 --- a/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModelProvider.kt +++ b/libraries/featureflag/ui/src/main/kotlin/io/element/android/libraries/featureflag/ui/model/FeatureUiModelProvider.kt @@ -12,7 +12,7 @@ import kotlinx.collections.immutable.persistentListOf fun aFeatureUiModelList(): ImmutableList { return persistentListOf( - FeatureUiModel("key1", "Display State Events", "Show state events in the timeline", true), - FeatureUiModel("key2", "Display Room Events", null, false), + FeatureUiModel(key = "key1", title = "Display State Events", description = "Show state events in the timeline", icon = null, isEnabled = true), + FeatureUiModel(key = "key2", title = "Display Room Events", description = null, icon = null, isEnabled = false), ) } diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png new file mode 100644 index 0000000000..e6662e8213 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8fc6f61ce73823af4b4edea7bb031fb15bd600b231df1173d33bfdbd09b5000 +size 43405 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png new file mode 100644 index 0000000000..73fd95a516 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1f3b861b5bdf266a4844248e54d36b7d47eb6b43aae2e877ef981b955b97b54 +size 37476 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png new file mode 100644 index 0000000000..12fc2a9e3e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73a6573fa506af844b8327a6a0da53a9a1bf4e222baa1281a992290423b22c5f +size 42187 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png new file mode 100644 index 0000000000..182e90be47 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4f0d016343bce34896e7983877c9166ebe97e62423e177cacc0f67b467e5122 +size 35121 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png index aca3254639..cec26474b3 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bea2b1b58e31957bfef5a6317753a11b4ef34477858af0ab9a515a57f837af76 -size 39307 +oid sha256:c0e3bbf4ad7201f993d8ddc280046d770812a969bba407e729a4726eda04072c +size 39369 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png index ecd34d97af..9c5abc5b8c 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44d8cececc9cf14291f2a23a762ed8628139b5fb3f15090b6ca0a2e733a3ac5a -size 39137 +oid sha256:90094980761bdcb3ecd10666af31f45be487cd06b81fd46710a6012610d25329 +size 39204 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png index 1c61185e1d..6d1b50bbe0 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61c4546a82519138144a2f1ab82f5200a0469fe428b06e2691f443e04df37ba6 -size 40217 +oid sha256:f98bbf43c73a0b79c7113180e117e8a7b391d4e4f1cb358aba8d1865bec5bba7 +size 40281 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png index b3452cc94f..22b46ce794 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ae3fa88e84abbc6d83ff55b613758118c03a37a99d7e95cc40369e5222edc2e -size 40266 +oid sha256:597ba7fae13fd3bc634aca0ef93e2e3626f552225b6848a5f7cff70fa04749de +size 40327 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 73347a5896..3840e5f38c 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -299,7 +299,8 @@ "screen_notification_settings_.*", "screen_blocked_users_.*", "full_screen_intent_banner_.*", - "troubleshoot_notifications_entry_point_.*" + "troubleshoot_notifications_entry_point_.*", + "screen\\.labs\\..*" ] }, { From 2bb3508af8ccad54d69c12123d76ee5714e5f7cd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 14:46:20 +0200 Subject: [PATCH 65/73] Use "BETA" word from Localazy and ensure layout is correct in IconTitleSubtitleMolecule if the title is long. --- .../libraries/designsystem/atomic/atoms/BetaLabel.kt | 4 +++- .../atomic/molecules/IconTitleSubtitleMolecule.kt | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt index 12a1dd1c80..2600b83561 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/BetaLabel.kt @@ -13,11 +13,13 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.ui.strings.CommonStrings @Composable fun BetaLabel( @@ -36,7 +38,7 @@ fun BetaLabel( shape = shape, ) .padding(horizontal = 8.dp, vertical = 4.dp), - text = "BETA", + text = stringResource(CommonStrings.common_beta).uppercase(), style = ElementTheme.typography.fontBodySmMedium, color = ElementTheme.colors.textInfoPrimary, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt index be149437f1..e38070e09f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/IconTitleSubtitleMolecule.kt @@ -9,7 +9,7 @@ package io.element.android.libraries.designsystem.atomic.molecules import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -51,10 +51,11 @@ fun IconTitleSubtitleMolecule( style = iconStyle, ) Spacer(modifier = Modifier.height(16.dp)) - Row( + FlowRow( modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally) + itemVerticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally), + verticalArrangement = Arrangement.spacedBy(4.dp), ) { Text( text = title, From 7ce4b47203aeeee55cdd3027b2834772c7f8adb1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Jan 2025 10:56:57 +0100 Subject: [PATCH 66/73] Improve current push provider test: give info about the distributor. --- .../troubleshoot/CurrentPushProviderTest.kt | 62 +++++++++--- .../CurrentPushProviderTestTest.kt | 94 ++++++++++++++++++- .../pushproviders/api/PushProvider.kt | 10 ++ .../firebase/FirebasePushProvider.kt | 3 + .../pushproviders/test/FakePushProvider.kt | 6 ++ .../unifiedpush/UnifiedPushProvider.kt | 5 + 6 files changed, 165 insertions(+), 15 deletions(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt index 5033274998..3eeaae1b2d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt @@ -7,10 +7,11 @@ package io.element.android.libraries.push.impl.troubleshoot -import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesIntoSet import dev.zacsweers.metro.Inject -import io.element.android.libraries.push.api.GetCurrentPushProvider +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.push.api.PushService import io.element.android.libraries.push.impl.R import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate @@ -19,10 +20,11 @@ import io.element.android.services.toolbox.api.strings.StringProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow -@ContributesIntoSet(AppScope::class) +@ContributesIntoSet(SessionScope::class) @Inject class CurrentPushProviderTest( - private val getCurrentPushProvider: GetCurrentPushProvider, + private val pushService: PushService, + private val sessionId: SessionId, private val stringProvider: StringProvider, ) : NotificationTroubleshootTest { override val order = 110 @@ -35,17 +37,55 @@ class CurrentPushProviderTest( override suspend fun run(coroutineScope: CoroutineScope) { delegate.start() - val provider = getCurrentPushProvider.getCurrentPushProvider() - if (provider != null) { - delegate.updateState( - description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_success, provider), - status = NotificationTroubleshootTestState.Status.Success - ) - } else { + val pushProvider = pushService.getCurrentPushProvider() + if (pushProvider == null) { delegate.updateState( description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_failure), status = NotificationTroubleshootTestState.Status.Failure() ) + } else if (pushProvider.supportMultipleDistributors.not()) { + delegate.updateState( + description = stringProvider.getString( + R.string.troubleshoot_notifications_test_current_push_provider_success, + pushProvider.name + ), + status = NotificationTroubleshootTestState.Status.Success + ) + } else { + val distributorValue = pushProvider.getCurrentDistributorValue(sessionId) + if (distributorValue == null) { + // No distributors configured + delegate.updateState( + description = stringProvider.getString( + R.string.troubleshoot_notifications_test_current_push_provider_failure_no_distributor, + pushProvider.name + ), + status = NotificationTroubleshootTestState.Status.Failure(false) + ) + } else { + val distributor = pushProvider.getDistributors().find { it.value == distributorValue } + if (distributor == null) { + // Distributor has been uninstalled? + delegate.updateState( + description = stringProvider.getString( + R.string.troubleshoot_notifications_test_current_push_provider_failure_distributor_not_found, + pushProvider.name, + distributorValue, + distributorValue, + ), + status = NotificationTroubleshootTestState.Status.Failure(false) + ) + } else { + delegate.updateState( + description = stringProvider.getString( + R.string.troubleshoot_notifications_test_current_push_provider_success_with_distributor, + pushProvider.name, + distributorValue, + ), + status = NotificationTroubleshootTestState.Status.Success + ) + } + } } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt index 95bfced7de..a11c6b147e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt @@ -8,7 +8,10 @@ package io.element.android.libraries.push.impl.troubleshoot import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.push.test.FakeGetCurrentPushProvider +import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.push.test.FakePushService +import io.element.android.libraries.pushproviders.api.Distributor +import io.element.android.libraries.pushproviders.test.FakePushProvider import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState import io.element.android.libraries.troubleshoot.test.runAndTestState import io.element.android.services.toolbox.test.strings.FakeStringProvider @@ -17,10 +20,18 @@ import org.junit.Test class CurrentPushProviderTestTest { @Test - fun `test CurrentPushProviderTest with a push provider`() = runTest { + fun `test CurrentPushProviderTest with a push provider and a distributor`() = runTest { val sut = CurrentPushProviderTest( - getCurrentPushProvider = FakeGetCurrentPushProvider("foo"), + pushService = FakePushService( + currentPushProvider = { + FakePushProvider( + name = "foo", + currentDistributorValue = { "aDistributor" }, + ) + } + ), stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, ) sut.runAndTestState { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) @@ -31,11 +42,86 @@ class CurrentPushProviderTestTest { } } + @Test + fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, distributor found`() = runTest { + val sut = CurrentPushProviderTest( + pushService = FakePushService( + currentPushProvider = { + FakePushProvider( + name = "foo", + currentDistributorValue = { "aDistributor" }, + supportMultipleDistributors = true, + distributors = listOf(Distributor("aDistributor", "aDistributor")) + ) + }, + ), + stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, + ) + sut.runAndTestState { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Success) + assertThat(lastItem.description).contains("foo") + } + } + + @Test + fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, no distributor`() = runTest { + val sut = CurrentPushProviderTest( + pushService = FakePushService( + currentPushProvider = { + FakePushProvider( + name = "foo", + currentDistributorValue = { null }, + supportMultipleDistributors = true, + ) + }, + ), + stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, + ) + sut.runAndTestState { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure()) + } + } + + @Test + fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, distributor not found`() = runTest { + val sut = CurrentPushProviderTest( + pushService = FakePushService( + currentPushProvider = { + FakePushProvider( + name = "foo", + currentDistributorValue = { "aDistributor" }, + supportMultipleDistributors = true, + distributors = emptyList() + ) + }, + ), + stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, + ) + sut.runAndTestState { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure()) + } + } + @Test fun `test CurrentPushProviderTest without push provider`() = runTest { val sut = CurrentPushProviderTest( - getCurrentPushProvider = FakeGetCurrentPushProvider(null), + pushService = FakePushService( + currentPushProvider = { null }, + ), stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, ) sut.runAndTestState { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt index bb6943d439..38a7135b75 100644 --- a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt @@ -24,6 +24,11 @@ interface PushProvider { */ val name: String + /** + * true if the Push provider supports multiple distributors. + */ + val supportMultipleDistributors: Boolean + /** * Return the list of available distributors. */ @@ -34,6 +39,11 @@ interface PushProvider { */ suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result + /** + * Return the current distributor, or null if none. + */ + suspend fun getCurrentDistributorValue(sessionId: SessionId): String? + /** * Return the current distributor, or null if none. */ diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt index 806eb98bf5..4f8c99cd3e 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt @@ -32,6 +32,7 @@ class FirebasePushProvider( ) : PushProvider { override val index = FirebaseConfig.INDEX override val name = FirebaseConfig.NAME + override val supportMultipleDistributors = false override fun getDistributors(): List { return listOfNotNull( @@ -54,6 +55,8 @@ class FirebasePushProvider( ) } + override suspend fun getCurrentDistributorValue(sessionId: SessionId): String = firebaseDistributor.value + override suspend fun getCurrentDistributor(sessionId: SessionId) = firebaseDistributor override suspend fun unregister(matrixClient: MatrixClient): Result { diff --git a/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt index 86792457ce..afb4d833d4 100644 --- a/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt +++ b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt @@ -17,7 +17,9 @@ import io.element.android.tests.testutils.lambda.lambdaError class FakePushProvider( override val index: Int = 0, override val name: String = "aFakePushProvider", + override val supportMultipleDistributors: Boolean = false, private val distributors: List = listOf(Distributor("aDistributorValue", "aDistributorName")), + private val currentDistributorValue: () -> String? = { lambdaError() }, private val currentDistributor: () -> Distributor? = { distributors.firstOrNull() }, private val currentUserPushConfig: CurrentUserPushConfig? = null, private val registerWithResult: (MatrixClient, Distributor) -> Result = { _, _ -> lambdaError() }, @@ -32,6 +34,10 @@ class FakePushProvider( return registerWithResult(matrixClient, distributor) } + override suspend fun getCurrentDistributorValue(sessionId: SessionId): String? { + return currentDistributorValue() + } + override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? { return currentDistributor() } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt index 03b754e26f..92d7c9ebc3 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt @@ -29,6 +29,7 @@ class UnifiedPushProvider( ) : PushProvider { override val index = UnifiedPushConfig.INDEX override val name = UnifiedPushConfig.NAME + override val supportMultipleDistributors = true override fun getDistributors(): List { return unifiedPushDistributorProvider.getDistributors() @@ -42,6 +43,10 @@ class UnifiedPushProvider( } } + override suspend fun getCurrentDistributorValue(sessionId: SessionId): String? { + return unifiedPushStore.getDistributorValue(sessionId) + } + override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? { val distributorValue = unifiedPushStore.getDistributorValue(sessionId) return getDistributors().find { it.value == distributorValue } From 678d3d4e58ed137df817d015db78719f16552cf2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 11:13:45 +0200 Subject: [PATCH 67/73] Set a sound to the noisy notification channel --- .../channels/NotificationChannels.kt | 21 +++++++++++++++++- .../push/impl/src/main/res/raw/message.mp3 | Bin 0 -> 22414 bytes 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 libraries/push/impl/src/main/res/raw/message.mp3 diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannels.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannels.kt index da5e0dc785..f5f0ce5cca 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannels.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannels.kt @@ -7,8 +7,12 @@ package io.element.android.libraries.push.impl.notifications.channels +import android.content.ContentResolver +import android.content.Context import android.media.AudioAttributes +import android.media.AudioAttributes.USAGE_NOTIFICATION import android.media.AudioManager +import android.net.Uri import android.os.Build import android.provider.Settings import androidx.annotation.ChecksSdkIntAtLeast @@ -19,6 +23,7 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import io.element.android.appconfig.NotificationConfig +import io.element.android.libraries.di.annotations.ApplicationContext import io.element.android.libraries.push.impl.R import io.element.android.services.toolbox.api.strings.StringProvider @@ -26,7 +31,7 @@ import io.element.android.services.toolbox.api.strings.StringProvider * IDs for channels * ========================================================================================== */ internal const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2" -internal const val NOISY_NOTIFICATION_CHANNEL_ID = "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID" +internal const val NOISY_NOTIFICATION_CHANNEL_ID = "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID_V2" internal const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V3" internal const val RINGING_CALL_NOTIFICATION_CHANNEL_ID = "RINGING_CALL_NOTIFICATION_CHANNEL_ID" @@ -61,6 +66,8 @@ private fun supportNotificationChannels() = Build.VERSION.SDK_INT >= Build.VERSI class DefaultNotificationChannels( private val notificationManager: NotificationManagerCompat, private val stringProvider: StringProvider, + @ApplicationContext + private val context: Context, ) : NotificationChannels { init { createNotificationChannels() @@ -94,6 +101,7 @@ class DefaultNotificationChannels( // Migration - Remove deprecated channels for (channelId in listOf( "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID", + "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID", "CALL_NOTIFICATION_CHANNEL_ID", "CALL_NOTIFICATION_CHANNEL_ID_V2", "LISTEN_FOR_EVENTS_NOTIFICATION_CHANNEL_ID", @@ -112,6 +120,17 @@ class DefaultNotificationChannels( NOISY_NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_DEFAULT ) + .setSound( + Uri.Builder() + .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + // Strangely wwe have to provide a "//" before the package name + .path("//" + context.packageName + "/" + R.raw.message) + .build(), + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(USAGE_NOTIFICATION) + .build(), + ) .setName(stringProvider.getString(R.string.notification_channel_noisy).ifEmpty { "Noisy notifications" }) .setDescription(stringProvider.getString(R.string.notification_channel_noisy)) .setVibrationEnabled(true) diff --git a/libraries/push/impl/src/main/res/raw/message.mp3 b/libraries/push/impl/src/main/res/raw/message.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..5e9645adaf1f2b7435ef29360c690b8ddc405d3a GIT binary patch literal 22414 zcmeGEWl$X77ygS5?(Uia1{-Wa2Q-NxVw`;aCdii_n-;xZV8s)4hfn->?FT` zopWB^m$&NP@26^acXfAFcR$rnuf12VZe=-sG{9egatLJv?C%2I-zM*5?QHGh1ypzS zvbXUETKEIil;xD|tj(=tHPqDp?m+RkS-aQ*e0_a+o$amc|83&6bano_`ak|t;6DZa zQ{X=Z{!`#T1^!duKL!3%;6DZaQ{X=Z{!`#T1^$0rfj>VEto}b;qOyyP>)(Bd{x(to zKv4=n_z(L30se=`|4{sg?*Fj-hx`8s{zu~f$p0U;|LFQ3`kmV$cPnLuR`_WU=pk^arz6L%@&eS1sm>B58=v|k6Y7K3jK66`LL7$H|QldxM zpu)fM1t&bIoi}}Vf81SnZMg{ZRb7$aJ^c7n=yfxtHnscqx3EjOi!fcn^5#`@Rn@%Y z@t?=n)IUfIi4?1s3v5(ENbkT^Aqg9Ap*SsDkx0|De$;Kng@UeRd$||#WhyiZY z*rV&N?6$`F!e2hWf5Z6a58UzS3!~2VkMBRe^?wQcY4&gW=THBa>sOz?z5n0iDeu#d zyEpWb#j@xqgqjD%Kx}D%?4y(vv4|!y`imbG-wXbHmn4cB_=N?_5k7%nE@%3aez<^d?p6WABm;eJ51wb_l z=WACy_ly(JM}@IR}51)xD&>xf;INz|FdPyG)Xyhmb$Q0wkX$X?zy- z^_2K&-61^ParNb!t&@U%0Z%)bAfy=MlXgb!$uM_i(fh=@y}hBYB4u79Ex=~N}Z>pyMKFv=NI0svCff5jV+>swj?440Zr z54nvBDuGTQCK^hX1SpnhgUOl`5}2`oQzQrrHcT*ZH%xZD#~Ud^T0RSEQ{x1_lCs@)`#FGx{tA_85s;+bYo}*9{!jB|=jZfLkq{<}a zJwrM`fseC5HG|>?o2TPG;qwdgDL4hbo06TO%iH_GC^Nml|9UruAg!79TuyW6 z%+7CROb~cP55SmXn0j~G@G0Y)(NQ&zh%QK+}q`d_NFB^WQ8-2fgHh#IAap_Yy>SyXy`Dn)Z{Ki;h zy`%3(Q;M~Rt)cI|G54EqnLlK)%;$U!T+`nt_CAe^<^Fov@oE3tdy~)pNsfo$l&bLA z-xm;MEW?q&;E5&Xe59|#nH7k^1{-w@S&18ozVn1UKtCcGz%^GzM;m;H6d(>k0V5Hp zl^DfBN7UpYUz}qb(I@R_TZ2;H7s8h@9q!E6f3!42d*0B)>;+C z8f8QMG9!)>#H_6$Tyi-Wz{KhMZk!jAh$)M{(*>2{(Q(-Q1NFpPMlXJl#AV6O6&^)X zp~8!z2@NS^qS-CUAfO+jz!5T)XcT7?N)`&&TxKQH^-NfnAitL7N7r%IQ5C$vrk)d7 z;rJ}!2QgP@#{!M>M;1@Xlg*gphXl*89LO_G+n7NHw-996OxfmHbC`<306;OG*=;lG z6=iZCUP)IqjSZe%0r7rhrDH+U{K)#o7h8|V$mS8+10u){Hw(TyYf^7!FLk)6?gx*p zw^!vtQ`=oZ?T`!psJ$)eXx=d<@}A4KPT-!l+{UK3`gwl{!1ebbCC?CJ%4?{8_T#NGN-4n$8~yyiy<8>U{TQlmnUB`DOH6mT>=N z+*GU>w%)U!l{#z0TIgdceh9QM3}~f522L8z0v<#OJ$N9L7FEWjl=y?@9ss}!&z`q7 zB^X_Y3-pn@k;w#d5t*1ZdW={>0f7VNUlyimo1`}ewludqw@l=jTq63lUyWDvUQ17V@gD%O)h3C_XH}MXne7n)jfLj zQkflI2T>McKu2m|&^t@nK{X75@ys$_lq~h$YYtXErc_D5hvc}6ox;Br642#6v#2%L zIFx~-sPvq@o6cd*ax{(MhH-K52a@QmjLEV#@R`)arf^YmT-3zM)apHehBNpXD~cV} zCY$7|UuJ606`X5Pw$2%HU(~ES^7t?ep?VaYdbNTsp&a+sajBJ!h&%84#x;+h(+q6d zAM_i@1rDL?0Y7VEL=7!)U4ZX2^@qfupZ+ej%7_mYkq>~#W>5!S4{l}5rp(aKlJlsd z0^9~0#Vu#|ZZo1GA;X_MM{{82ZdMqoI8fkZ{K)4lLu{jrF2-jL#Htdi5PN`oH75GV zK+r9%>S2Kp59@nVtIG#h=ju$J)o-*u>k-ty1J;EJ*W0R$Eb$3zhrH+QLPfTFO&tTC z4x2i&2#Z{yMOoXv-|n9NWT@!(>V5dZ_v%vkm;T$l_UaRe%)lK)Ec6>B!2kqnP0tPqj}(%aE=@|_xRw%oMKI&(|{r_AenX}EEqeiXwB+pHSvMr&o{{t zgU&K|PYr~bB-dhUgGMjYE4Eo!M$Xgqus&KkShyNQ$kN1DhOW1J1mVlj!2&x46kqgz z*9%`xLVfNN!_+*n7cs|eh}J{TjO>t`dhe{6B0h`dDbVAxA~Cf6&=}HC;pjxWvWocO zHuk5*^PN%UC?8{?!SC;H9G8B7{sUiDQ*V0xr^eEiI_9_IpEd75NB=xVgYL(*{y(3; zPu`jwndo?&(+0Z1u?MgrB=|a%0B%T#2tRgIDZe!i8ZOBjNDYo9+Se*bJ@&P^k|ZmV z&ag*L2tsVu6#Qm(>TIki>o%)q1*U3>X9e^(5+Sc@Ou_b6=`gr5|FaJ~tcl8_aw*c? z!72BJPj|gRkDm&HmW>{q8#eROGIOu4e8u?!#kx(~@}!-ZQoiQx={vk3c${^u{WHP; zj-*=q#n(gIE26m^M|*$@nwnup>JZW}#0~ixb;{g4`@l9YZo!ozA{ogBctTc&IML$| zh7bZsg1t~CLtyAy!EjV5bO3r_I~72e1s;ql6&)U-xniB(zS18%)zY<=m)|CIQnC5Z zzdQgcq^IKf7oM-jUz8MHu?0O7JtWaMJsOtiEndIK@wd><{1|;kO~)%AT_kVCcUhg4 z;86MtbI#7od*Ler7el4%T&X+A79*p;-}5ZaZR+Q%LETJ(%9s+qy6%4}-zV#k9eFjm<zzPEwK z#qw>0@T$Eo%jLsbeM((IV4!O~x`1{?#^3%K09lRBMqxf;F;mIbM2Bu^2f^eE)wIw? zWy1`iM0%k`Vi(6FcTmRwgOW&m!bn_TG*SoylWJEA7p)8+#h}y{kXDlp^})|V3#DX` z(AC389zLhdZKKtpF|i(ugH*S_8*!G+>Y$LIyq4t}bkxxcME;Pd9QRt1V7k2dGQspo z$<^qsC}YH)G)Rd}YJb9h$^X6EO{cbzO0mH+{AbU^2W!Q-kFQ%du^4BIET#)!tZGEl z{)gw>hlUfiz9+h4JmeHu`bimC<@^+j;`SYijh(*uKU97kxy>>i^Hku5RrEOs0Jwjp zGEZP)e`HV~C8o0xQEF0jb^3z!le%1i8pvaVlTCn$(Ts9zm6JwkvqcRoX9~9<6Pd2G zoL02l^14Sk20rOx*H-ypo{`t#--G+s;S407dC?M<>FioZEtnQIC|{;2P)@F4GFANgnDS^s&a5TLE#s@-Ru^9Hz>-jfws4c!sFJr> ziYRd|rggw-bxhn;w;Pn#QD#i`%CO96dh4`N#r6x$X2#u0;MKwx zC&Br?-J!fxCo>|~IJh$KY1sio+ImIUcm<+ZPsCq{n z>`AXA0#Un$SxUd07FcKrU7MYFK zZo%1T;i`K}{aQ1o8To`Vp@9(1S?&>&!%te&v$WpONO~-S1HPsq|+*hCG9Uwu4u~o^^dmej%LIr zP{>8n008u0;(>g!8R7V^%h;?^+Zz%L13Ri5C@nyICCtQAkqa1Q))Lq^v$r#___Wk~ zXvDG_mpHhXQ8gl<*O&sILeg8EQAfmUUkl8Pr!g7t?p6=p^kh`>s;yG7>C6<<7!Er0 z-Ck)G);Wfb?hkKhV9dsH zqDdm?*P8a65VhlTU84_KzutcO*qb!VJ{EKsJ;<1As(n?m^y%Ab<@_8M2=$lB;kRk}JJajaf+(48|fWc9)q= z>867Z4e}4QU=!oTsHFbLcjyO z*mB2Om>UJgs8!lQP|7+v+3L}wqxuKx78bUXd9g2kIni{5$bFTRhfH`p^@0WSSm=5F zeRdmVC7y&WCtJGL#|w9RHc^%c)PGf8N?>Ip5CHia(21N2-m&OqjP%$Km~df=bwVzO z1_h)l{BCtn#*{-?m6Z*JUzs+^w7IX-^(Q8aln|4n`aKe7U)h8cFdQoj-Rey5M({_%PxZlc-?tNrjQ)td!vNju-$V*k3U#YZ4#TL{i;vT0lzBD;bB(pJ0 z=p`nUu7>wab>J5}AI(W13t6E+CX1=KR;)tb2WOJU)9jWdqgjf=;y(NClbnjDE zi#UFa#^s9=^)#3ARtXz70OB$M1b{FFM?y5DhoPK!w8B5zv-w%&VG#GhH_uhkBK!p_ zWQDk4S|qzt(%lcP$1b^otdqjwn-tl9FiBPl#gayqcRf66_1iIjFb@xU$LgmaZuj4L z-KrHxZswk7S5Q%j=Ft$ba|}gBYe$}QI_YT7bFHeX>=yZuE$i+MlYhBEchLM5*eCb7zoo0`r*p%2<&x&Nj39GM#Am;UyT_;P%EWI5&bfK5tNe~?am$a+ zWM9@Cy3f$tEGS)HE1PuBD|rfi>9+KJC{J-THF_MIx36fs94e=`uoc&rV)h?3kEE{8 zgV)5=CCg@`0v2r-p_aq@p|@7aF=$H4jJ(R0EKJP$wiy#D+O7Ke;ur zd$848ykz9}utxu)$Xgi))iDIZx_EyiY~VUN2sVAtdWP~?$IHMg#=}T74A-`M<*Hn5 zIGcMdddn75>u&LJM8{xXw#J5pBv`q1a5xexa=@8_pwhDSyqkeVs$sdzeRmdRXc?Ed zG2QXXnfa`qUr$dhJ%r^CJxzl#gIn`EE7YQ2bK9y@*%k*y*`f`hqqU~$P}0r1GV9pK zCmVNIr)QjSS-(*Od|a~8DPwHY_TC3^#kSp%?LWO9nele3B)s0DS54;jeoZS5yu^N$ zy8{69NC5`uFo1vkE9aAtMei@o|HB+|r6I!kCZ5d<;}lh6H)gn6V#n}TbIyPwe)y28 zQ}wjZ`Nz=>YLUTHtdaHPGKrd*YA0xL*BH`+Nt#%aOR{U^XA^D4VVs?MGrdC4b+mSI zE%mS1xJZS|2$sF!sBuq{g|BU+ScavC*z1f~(}4X4&3p-Cz#CcZ{e->*k1?{smFUwY zgHLAC^1dJCkL@g+Nb>m-<1}*g{Vd{xTaKulVVzGDH2%93foTM8%r{Q%dN=D|zfE+D zZ~9HepKf2RPkp$1O6mRTO$5|49nGGhs$(q&De`f=0Bs2ERM7LjrAztTl_9I#!%UsDRD~Ij_m$#rN+|y#EGL-+@^V`s{0 zM`ahCSI!VdM`Oj-x<_ZPGyVA`Ub0?AAr>rPb!IcN*Lt{GlHl&P8_a z5}j)4^o{zTlxH(Lmp2kj zPbCwX18)OA?2gT6Rq{4!-{|ATkn?c%tF$?{xGYm-Eu)3=XFZ#&YgEV?=b%U)h{7Nq z#KpZB7I$dgquTacB_yXFw8jiyg~s1+O%ujIpnZ7s?n939kF zPYWY1)sYB>;9HJrU|KSk))xHPVrEfHy3n+>wnhkP$mEUn+hT!XVN+6*x6MF$U~#4=+29GYF*CFtSEeg@>S3Q#)JOip`(40u8uoJLsOPc-{jb{ z)2-LDP~CCd7L-je6=$GMa|7KDK01Uho;(;$)i7m@h;}Q7kQLY#Pv*urgR(<_j>Igv ztqoThY@7Uy=O*z&BjP!}OpviWIQnb__Nx0HtyKRERpnQRIR=#rEYBMMD|ji74pUa@uD$V52T1(ydJi*%IRg6p&BA{aQl zVm9-)%fbR7EiIhd73b?^-tqM>OCI-|O2|K4v3QsL^RG+7hg^Rtyf4;nm-8a1Z@59` zG-p5gE)T+PpTC^^1xXISpwIZ^YNl;?WR5kXU!Tr`6xvj3Z&H%G-Dv;l05UNZvk zyw|gL4)E;;8Bk4TPLl6BM@3SaO%z~(W$(aR&MDR20lF)q7=Uz^Nfa&ecdBTzJ0R+O z5)%^(__J_3O&${Ny@=tf5(Z#+xQUF@HX+b7MV4_F*m`zc5;FR(>*6}R{JGyqpJ@jr z_T;v=BSGom;n0_y)6GsT6>T!XD!GpGnw`w|W$SAcQyLZK{;zY&M}##HENy-=&*rEl zd`LH}$B)`j_2Q-rbrdJnhs6<`-u}c1s_G(3V3`oGFVwjXv=io)XPo^rh~f zAD2=LwODql*)b~9WLA`fG-ICzf2U%Kdbd=ws*wXdIKaaRr^JHJyvQ*E1k2HL6N8aJ z>7|*8Ce6C7gbNNm(&k?A)QfXvIzGdU>BNJrqqL|tnviavwU_f~Ka@P^FXt|&;em34 zyJZhEDa3D^O-qZJxZIN05RWraqMUh<#Y_x|FNVtT)F&+dHJ2F*bl*0t^#yCK9i>W^ zirfg+5$(>FD+VV<-Sm|XuUE1W)wxue=`+_KpUuU_4=o&HaT67;;_GslHZnTUmfs*f zE!;$RH|X1#v-R_co;a5(4h@x8vNfg}3k4`P((rMq@h|J<34QBp?*dvx!vi8)T%Pdc zcQsBP{rl&mo?7|CK>3eCXNjZ#CK*={1GwiJK=3n8*pi&3#@la`9 zz}MJ%Z!^F4OeJ%_bQi|#`apZB*7eu03+7U8UEFx`EDfc=N#n zY0Wxl()vrp@R8zSKCc8T4beiS5j*H5$?w7}-kGGAiWhWA@RGG^V>A*hL7!Mu% z5lQWkK!Uu%)Y!a7;!_1%&QK9A;=`&ws>a!IBuN!_&u|l~6LRDUaB@I$WpE*y5(7Yx zebEI)Wv9?gX^!z>kH{w%>kte@n*CH~)p~WR#WO2c%b*EInp*m1o)+0afqFFqEkThM zQdWBXh{?jZaTT8oEJ34-#&}=ejJF$%5A%(+5JOs$NK(^-NtSE9;wiBC)4 zTmSi28Sv2{;62_?f5=ml{>>XFHhR`$^!dy1xRSmdoWJqcR6ZciU3Ftw$Uef9gd?E! zz4*%I$=I!VOAkIxF@GJSs4zrKYkZh_cR60yGH$KX%Tf)|;9n@#(4?NTMeWhxp~FO= zJ}+=_?$OlwV#TjY>vz7bRq{!WIEtxVq6Xu;fR&eJUBj{EN$C48{mKo3*ClN0Tn#_) z>RSQOFbpV{G2|dFzVCJ*;Qiyqc6-2hHr1Iby0H%Fh#9-G_MW@~!8f;9ad5$3h94$yE;;cNxH1 z4ULJt=CZtHwstBdZ^Qv>sSFx>QUhm)Om0P$uV{;1`(CO+iq*XC@mj8WN$;sTqi_J4 z81>L@%cAv&xXCqM5*3BU%vr&MUI*(hDTP>U{D^ze5{R8R$W<6F|D;Jg_&484FfhK_`QNz$OcbnITI6W2p(y0)Xa(0Pl zq+xsZ?qat(B{ayB`~wiOp0t-{h8?uBpS`zEhn1BuRrsujm2lKG!N__@Fp*IUb+|OJ zM!%4C*u(g3RQ+ZzGuV;nctf4Zz!5F37YTpro-u8O$Fq2zUXy{2K0 z+fnVzG6YVa86N#X;qZ79aa~f&mOm8GXhf7alUaX9s&$9o9DO}{oIbQiGBk=~ZiCf{ zQ?3}N;>xF*7oVtAJq5O#?P`47wC;m^KZUP5o)kF?qJs^k&`=jpbO%0K_|;e6oqA0Yc-&V2O60QHR%h{5?BFyGHL zoFwtrzmOF7<#u?Sau#<@Qjfc+ow(-E9&jlju@`*ExkK=T7R;{t3)S()DBmq_t(nHl_Gh|J z)6I=*`de$dy1-uc#47Qo0)BKauT!SQ;mf@BS1Lu;_lk#k1A1Zs5eC#@v8x$iy`J}k zpDKA=V_n-*2qg)mkYs>%Bx`6YvXfE5YJ%&?g%R}(6UzV{gDF@YKoiUXfKhXrnB&>C z*Duhord<8TkLMx!B<`c98$I*S}a!DybnSWmNJ=iRZGT1Jdt zEXOVfubV1x)|m?{7>HNM%(7|aT+>_j^7b9x&GbO>AXj;LQc%q>{gQ02R zxiP)vxEyX$$8OSfq}J$YD9o>uXV+B3uIn_obtp5J*~`!_2+RdF6^a8%XgO&}>vY1_ zC@GZUuC!y^W3TUDiW$0%nHiLEzwS4N7n=D@d9p8@J>8uX^3+XplSk=dF7#=*TON*n zp>B%EV`pa7M{%h-b&tlUOB6{mzjV#ba=GfTiBj z@UMTro0DEA=|8-|XQt;lMx8$mkE?l(#Q9d?mh~|ai@9T4#vA4j5AX>3`aStne02C* zURpFLKEDG653j!_)8vnOYm{W)`Zt8Ie003TVC(cbtwxl}OQ`$9Dq}ZqQBmiGI|bM+ z=T_Kow8>OHsLss9K=MsSPlVb2`eU-dZ*#0bg=(HMPvS z^lCO=j>5zWj`k?&Gw$v!t|k<0{6Ix@TGW(d;rz zVd&6D{J!SQ?)3Sdojb$EB$p;F8(s2s18rE1WJF3Pi#2{X-4spuQ8Qa~&-+3HvmTn+ zoStzQlA7d}v66TsgM{}4UpyC3ZwO4DUs1uTWhIb#oR)~9J|C-)#Y7kR z=u{l>+H*cOc3Bth4#@0qKh--poIH^(kQ5WGDn-16y*|#7O&Zn(V%$R508)@7*?0kw zli)223PdsvI>W0z~KTdYrMdWtGHf zkc2cH`9)E%sQ@>H1>7Od9>$c&m^w=pF0VdxshUdA;)KTzyw21i5rC;)i~8kjc~Ei( z%F`v9+NZ z;O@VXn+L;eW<-bw@P5vDwNAxk#FNlioS5SLhDT^?Gn1faG14;uo9_%U2~avMV>{RV zZFs{U-nvg(9B{0H<^C6cc@oyD1Ek2Fl!3GJBBZaBL52~Z0UFkzIN)FZUX&+`rX0|9 z!c+fdgiXK)>LR75z+4(|9Xl`rkE~WR`)o|oRK&_dai=9n;yPyyi zi?#JkyG%XqB)XxhyfF6BK(1XM4snX8ur4UZm!R+Gbh-cRVp^i zAT-O|F$O=<0V(3KX1lVN$gN~T1ZWlIhG&y`JGq|a$j-J79Ua8fv{4v$J!8$yBKN7R zJ|1|HyFrlWw7Nr5p7b7SZ3D#uM>K_;59OHRr>rNr9!RL3u&Nyb7PmZJGm zRq0x7(c9WO6hT$l^_JL9+H6wJxXJ?X4X%(v@Qv0lp_|VFkUDT_ok0KTo(JXMEY9Da z2RlRD9YY+`0fF@Oqm9>~M@CEcBvam9oTF+`~1vc48=(M+E3g%$@P-f85 zY(T-L&J`=4$CC*!QpaiBOLm;%OrAs$daO^7e@|Ma_sYGJEW9$M$A;800Zz+4D-_LC zIfA0s$-`8kHNj?A=@iOZToAtNl*%|M8eUg6F+$c|xlCWj{VlAu58I*3R!7q?)0Nrr-MB8 zH&fFbiMj&3NG{9PSB25LYaVtIB(RO}kXnQ8RuC!fCz%PE+8H&fJU3RnJbCtCsi_KA zps`Zpg2{3QfjJ7zj6IqttkgJWmqG@CpY$GLf=Mce7d#HJs_x}9adoL9Yi)iCT3SEi zA_GKv%97#Js%>A(m*IB}R`(#amAUj&LE6U(;C;kZxt&@8!B+?xKBiRuupb+tYQ4!^ zJmpv@q!=Y{{W*7HeNS9^VT0iGY@GG9Ig~}-*#bwJ+Ulp3ePz+W*rr~&t<1%Zw_JOS zhnz@nR@uQGPbuzuO|x>Xqs|m<{qVcB}I!bHqw z*M=S=Jf7viUcMCcF){-r$B|6VkmoL%XK(J2IH)q8>Hms_D0rKiiJK$3%xsxqTHeHb z?G}&Rl!Qk+tX<+4REz{|RDB=jjN44C{kMQYgjNP@Dx_*rPJTmqmBm?!2XruqYTQ`R zcCNu`pQ8LF!1Y$8&?&#qRsihq4io44r0YPLebm0Yt5T4P8Pc;^)4Kai&4QJAnsGHG z9WlsUu@zGy_im;|^!&T(7D=I+4)wI}oU2KX4efIaDPKw%cZ7LZ$?skWpX5fJ>ee_h zS-u6&+qpI&eMN(EUJc!}GnFxckO^%)4pXw`fa%(VvU95E{F5}xa%yQ*{r}JRCb|$5 z)P2A}1cX?FMaO|oNFH?`3rY7PSfm8lg~`MgF*3vz(5A(z3Dzk0Fv+N7elJbxMQZ&p zaoe?CZ^E6fC z(!6yWs;;8?`tyTnD%gy%P|fb6OU7Cpc!Yv;;<6@vjnj}AK+Fxn#r6b@LIm0BS~$lb zUVyJJ!eYOTm{$L-0z{N>O@Z~4iihc_&u%h?j;YfMUW0z{s1)JRGq>Qe(MKns#jf-A z*la0#Q{cQ5mzAHQ(&KQ6+ljp&Jy<^|eH$y>ZiC;MP`E)Ef7P6d8ebi$+}cLko2ydZ zBG8xvN}CzHYNce$!{NNnI*U(Fi7GTkSIU&zEZmAb){h`GJoR&c<2KkFAIHo5^KS>i z8cu*@*hgi+V3Y9TD;$u4?$LK1f8aEl#7m4O5Dj~aLG!~kE;=iV%6%EO$Pnn5A75x> zO^y@O)O={qJhe>0g-6@P0)LD|N(^ZPkd$?f zr=^<^Bo+k%;UNM{IlhGwi>amyL_bXp7;*ypI_%%<1wx0r@wX~|cl19cwKj*{!4v28V} zLUR|CA`Ni7OaA7Mv&^sWtsY`XG09&q)k2`CW!O?G&<;3Dh1aMA9sV#uFsB$2r#J>r z6T%J3%;I&64j;atn9U*@e!KwP&cK^@TU(SmXeR!&tK=tNh11w*{7hlyC^T8#MhcZmQ*Ws~Enx%pA`s=q0c8-q%gN2Ec}>X9 zRKv6Nv{t^ksE#-;LY8GuOC9>?t}7i%cc9m3Xp-O&fx%L`WO<9?AFf8t%}a?SK?sOT zME>CIGU0#TQ)z(40u-^-p-)d18?@JHAr6AAIo|hti^Fbd%o2|E|)DuvDt>*D*bp`2Lh0S|VTzdkV7>CQj`ivcU<)A2`8{mmH7Z zbP6Rjl_?(FL01T&&i?1$KQSL#1H{8N%!$A7>ASnmVAG!-T+Kg^nNE|~4!LMf!60Xd zDTsU9Zz`5j(P_W+OeRcsS{!k;^G+Pd1ML)3$!*1K$nYg~vNAIGk`tw@$h4!^o=YIj zp}OtBI+G5#cJCM+BbdHmx88W_d?pc#R$1&x#oD+|dPGo&SnjY^`9ePbOqB)kO5}U$ z_3hYdX#fwq$uaSw;&F^_2E5Xq$kA$?mxU`ozvtF%-+HO;#IZWSl)Jm(-Q`kabgd;r z5@9D+`a(Uc!lc*Zn~eD1b@+#O{9`p_(8*du-41`~D`WGIrjijDmJ=Lui8#yk$ari8 zR?w5{5ZSR36EP|osmN$KPr%D=qKVrG7tOzgl4xug?ilvY{x}sUS~kW ze3Z#?aa6q8xp*n}fkp?=Q=H}TWeF8VLRFw6&}g@|;^A)=o+~k~VdeTxlj83C)@<+jYpUA>s5Czr5o{z2)|VHGorBSq@)IPuFeK1V)%Z?tvW@(*;z$C8}C?Y zN~7H)YFyrmVk~L~bMj;NOotEdak$qpa~Y$iSHHjB_cJ{$M?7OQ2|B7YdW!Ft7G>NH zD!K>jHI}#E!&A*4_U?D@IscBhf^mT8WdMO!P(>BX_~efe5DIJ)ZXP{StGqo%vvJ__ zq+q4DI#adpB+}w^RIfSu0vB!4%!+!Rcy-I$qXbu-tRlQr8%;*)m#vvzcfTT81UXw_ z^U%o9+iG@AM7*9y^67&03CBmnF69_673?(DW;X)Vy%Z=4g4_=rrN?9?)hx`s-JFp} zLTeIXVXhHN3S*++vLLats7_9kB&bHy!X>S1Rbdw3JC@ag*~>W&x^cues|i|1q@ks5o*q7YWM!c|p_9y@fesDyGWYVoL~Lpp0kLO>e;&|?|XI@ z^}bd|R~aA5YX@2@Ug4OwG}6IIuEeE)yNUXoUb)9RR^~X&$&MOH-gS$WiZWF96q6{6 zmLDpV_4Y!X*;^XETc$qX8;=9d?X+4h#G>E>5h1$e9qigC%B=j}@aE6MM3iN0O!-aftxx&4I<3+D);G3_8jXfTs`2*dSmo>9 z?x3+svr~$miWgA$+f1OyQ=j+SxH-DQ>?TGPv*b>Ln#CC#{pi|Yc7^OiOZF%YCNURJ z*;bXe(WkHE+N&tl85<^&GKAcQ)rH>1)Jw#`1TfoAwQ;&@VnZJ{LRXYwRoA=`%7dm9 zj3uc(MFu;aArxCi0p69oMXdGmmgVmb^~4S-S9@d-&vlKMPOmYH?VMLRzI!EPWn@s* zBVsSICL!HlJzXc#(cm8G=D`tc)zQJOLQE){P)q=`a7|e=+FHAXTmsowPJXA@l3^5Odnud>?)0@_;QI1FIHi?ktSY4H`j=u|bYVL_{wDw{>wyXt- zq)0~pDnIV4Z0!5o#M|i2x@~Fs`qZmHLC>VZN`(-!vaF8Z~*SaunnycY$-Ty{m(o zF|@k^B~{dloTO?&O0&kP)*)xIJMk&T-YMwWxanZ*rGjgG1Z z>3T7xfMGK3p@EnscG_~e0_exX=o4Mly464@UM{(P;PB5CaqF(H=;Ol zI`gwuC1yV%5Q~x>0W-)y3sH?K3xxVaOR{ToScZu zWzd%j_Q>zvS+_rcpZIjBVDemBP~8W3QI4@6tg?z^O0*BY&BmNmGgrY#MC{LJH<#Zp zai^wKsL|AFYqu@pSk{phHtlL_eJT32?vJk(jfVQ_j)1KS0odIK54%UB&;Ne3iu?qUz_4$^DVSoo>q^#p1Bg52BkPrJ`7 z76%>dOt~8@##h=H>*KCoV^?_ zCKhf%#t;1?*nO6Q!Dr$D>G{(2^Yyg^E}fmny6r{QdBZ z)J6ysw~|STBi{v>o&5-1o(Sh8zFU~YbpTP2=dajcr<8jmm@`!)G^?ZQP|e{(l*+hw z1ZwsV~Lc_i%*DA_$3F`qK+$(OB90*F78ndR;jU6JTCiTpfi9u0pj?Vqx=|+5D?YOAuY@Nr;#X03t3GCQgi6NOS`5 z)Rg82vPwu7$8(_f$hbQeI>r;bl!R`{Bn#*H6Q~^j2AbK@~#05y9Gy~9=BR`7E$OHlB@}JdGIJGM3 z<(HF(SDSltjfjMi9(^PGeh4h@keS}$NLrZ^yt8Q+Lbvw9`5@n2kx6>cSuzLLk(ZgC zK25{#tf9=3JC%dSr8x6~sT5(GD1WO}D%nr$r^0K}HCIL_6Oy|b_Z*%xZ>WUdap@;l zO&wf|S;?lW&NgDZpUIf_36xY~OzPEyzD!~=g=!w&%4ZSj%TE&OB0j0*vRCI;;CYJC zdgOAqq?eN$Yd6i3b&biUu}0#>(x+$=X-kb~UosQgJyzJc^@LF=Svt+9u^qd_`-X0AM$(kkml zr)RIeD6a>9yc?9qrd9OxxK({5OH?&|lvcrgR-ta~TmFY3Wm< Date: Tue, 7 Oct 2025 11:30:58 +0200 Subject: [PATCH 68/73] Update Localazy config and sync all the strings. --- .../impl/src/main/res/values-da/translations.xml | 11 +++++++++++ .../impl/src/main/res/values-de/translations.xml | 11 +++++++++++ .../impl/src/main/res/values-fr/translations.xml | 4 ++-- .../impl/src/main/res/values-nb/translations.xml | 11 +++++++++++ .../impl/src/main/res/values-ro/translations.xml | 11 +++++++++++ .../impl/src/main/res/values-da/translations.xml | 2 ++ .../impl/src/main/res/values-de/translations.xml | 2 ++ .../impl/src/main/res/values-fr/translations.xml | 2 ++ .../impl/src/main/res/values-nb/translations.xml | 2 ++ .../impl/src/main/res/values-ro/translations.xml | 2 ++ .../impl/src/main/res/values-ru/translations.xml | 2 ++ .../home/impl/src/main/res/values/localazy.xml | 2 ++ .../impl/src/main/res/values-da/translations.xml | 14 +++++++------- .../impl/src/main/res/values-de/translations.xml | 14 +++++++------- .../impl/src/main/res/values-nb/translations.xml | 14 +++++++------- .../impl/src/main/res/values-ro/translations.xml | 4 ++-- .../joinroom/impl/src/main/res/values/localazy.xml | 14 +++++++------- .../impl/src/main/res/values-da/translations.xml | 6 ++++++ .../impl/src/main/res/values-de/translations.xml | 6 ++++++ .../impl/src/main/res/values-fr/translations.xml | 5 +++++ .../impl/src/main/res/values-nb/translations.xml | 6 ++++++ .../impl/src/main/res/values-ro/translations.xml | 6 ++++++ .../impl/src/main/res/values-ru/translations.xml | 4 ++++ .../impl/src/main/res/values-nb/translations.xml | 1 + .../impl/src/main/res/values-da/translations.xml | 3 +++ .../impl/src/main/res/values-de/translations.xml | 3 +++ .../impl/src/main/res/values-nb/translations.xml | 4 ++++ .../impl/src/main/res/values-nb/translations.xml | 1 + .../impl/src/main/res/values-da/translations.xml | 3 +++ .../impl/src/main/res/values-de/translations.xml | 1 + .../impl/src/main/res/values-nb/translations.xml | 7 +++++++ .../src/main/res/values-da/translations.xml | 5 +++++ .../src/main/res/values-de/translations.xml | 4 ++++ .../src/main/res/values-fr/translations.xml | 2 ++ .../src/main/res/values-nb/translations.xml | 8 ++++++++ .../src/main/res/values-ro/translations.xml | 3 +++ .../src/main/res/values-ru/translations.xml | 6 ------ .../ui-strings/src/main/res/values/localazy.xml | 7 ------- tools/localazy/config.json | 1 + 39 files changed, 169 insertions(+), 45 deletions(-) create mode 100644 features/announcement/impl/src/main/res/values-da/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-de/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-nb/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-ro/translations.xml diff --git a/features/announcement/impl/src/main/res/values-da/translations.xml b/features/announcement/impl/src/main/res/values-da/translations.xml new file mode 100644 index 0000000000..933ae95d6d --- /dev/null +++ b/features/announcement/impl/src/main/res/values-da/translations.xml @@ -0,0 +1,11 @@ + + + "Se klynger, du har oprettet eller tilmeldt dig" + "Acceptere eller afvise invitationer til klynger" + "Finde alle rum, du kan deltage i, i dine klynger" + "Deltage i offentlige klynger" + "Forlade de klynger, du har tilsluttet dig" + "Oprettelse og administration af klynger kommer snart." + "Velkommen til betaversionen af Klynger! Med denne første version kan du:" + "Introduktion til Klynger" + diff --git a/features/announcement/impl/src/main/res/values-de/translations.xml b/features/announcement/impl/src/main/res/values-de/translations.xml new file mode 100644 index 0000000000..c38a9b5cd9 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-de/translations.xml @@ -0,0 +1,11 @@ + + + "Von dir erstellte oder beigetretene Spaces anzeigen" + "Einladungen zu Spaces annehmen oder ablehnen" + "Chats innerhalb deiner Spaces entdecken, um ihnen beizutreten" + "Öffentlichen Spaces beitreten" + "Spaces verlassen, bei denen du Mitglied bist" + "Das Erstellen und Verwalten von Spaces ist bald verfügbar." + "Willkommen bei der Beta-Version von Spaces! Mit dieser ersten Version kannst du:" + "Einführung in Spaces" + diff --git a/features/announcement/impl/src/main/res/values-fr/translations.xml b/features/announcement/impl/src/main/res/values-fr/translations.xml index a529e99100..04a35b0fc0 100644 --- a/features/announcement/impl/src/main/res/values-fr/translations.xml +++ b/features/announcement/impl/src/main/res/values-fr/translations.xml @@ -2,9 +2,9 @@ "Voir les espaces que vous avez créés ou rejoints" "Accepter ou refuser les invitations aux espaces" - "Découvrez les salons que vous pouvez joindre depuis vos espaces" + "Découvrir les salons que vous pouvez joindre depuis vos espaces" "Rejoindre les espaces publics" - "Quittez les espaces dont vous êtes membre." + "Quitter les espaces dont vous êtes membre." "La création et la gestion des espaces seront bientôt disponibles." "Bienvenue dans la version bêta des espaces! Avec cette première version, vous pourrez :" "Ajout des espaces" diff --git a/features/announcement/impl/src/main/res/values-nb/translations.xml b/features/announcement/impl/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..0765e557f8 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-nb/translations.xml @@ -0,0 +1,11 @@ + + + "Se områder du har opprettet eller blitt med i" + "Godta eller avslå invitasjoner til områder" + "Oppdag alle rom du kan bli med i i dine områder" + "Bli med i offentlige områder" + "Forlat områder du har blitt med i" + "Oppretting og administrasjon av områder kommer snart." + "Velkommen til betaversjonen av Områder! Med denne første versjonen kan du:" + "Vi introduserer Områder" + diff --git a/features/announcement/impl/src/main/res/values-ro/translations.xml b/features/announcement/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..48fa06fca4 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,11 @@ + + + "Vizualizați spațiile pe care le-ați creat sau la care v-ați alăturat" + "Acceptați sau refuzați invitațiile la spații" + "Descoperiți toate camerele la care vă puteți alătura în spațiile dumneavoastră." + "Alăturați-vă spațiilor publice" + "Părăsiți spațiile la care v-ați alăturat." + "Crearea și gestionarea spațiilor vor fi disponibile în curând." + "Bun venit la versiunea beta a Spațiilor! Cu această primă versiune puteți:" + "Vă prezentăm Spații" + diff --git a/features/home/impl/src/main/res/values-da/translations.xml b/features/home/impl/src/main/res/values-da/translations.xml index b5cc2ef7cb..b686fb6e03 100644 --- a/features/home/impl/src/main/res/values-da/translations.xml +++ b/features/home/impl/src/main/res/values-da/translations.xml @@ -3,6 +3,8 @@ "Deaktiver batterioptimering for denne app for at sikre, at alle notifikationer dukker op." "Deaktivér optimering" "Modtager du ikke notifikationer?" + "Dit notifikationsping er blevet opdateret – tydeligere, hurtigere og mindre forstyrrende." + "Vi har opdateret dine lyde" "Gendan din kryptografiske identitet og meddelelseshistorik med en gendannelsesnøgle, hvis du har mistet alle dine eksisterende enheder." "Opsæt gendannelse" "Konfigurer gendannelse for at beskytte din konto" diff --git a/features/home/impl/src/main/res/values-de/translations.xml b/features/home/impl/src/main/res/values-de/translations.xml index 0596dc45e4..2502df5fc1 100644 --- a/features/home/impl/src/main/res/values-de/translations.xml +++ b/features/home/impl/src/main/res/values-de/translations.xml @@ -3,6 +3,8 @@ "Deaktiviere die Batterieoptimierung für diese App, um sicherzustellen, dass alle Benachrichtigungen empfangen werden." "Optimierung deaktivieren" "Kommen die Benachrichtigungen nicht an?" + "Dein Benachrichtigungs-Ping wurde aktualisiert – klarer, schneller und weniger störend." + "Wir haben deine Sounds aktualisiert" "Stelle Deine kryptographische Identität und Deinen Nachrichtenverlauf mit Hilfe eines Wiederherstellungsschlüssels wieder her, falls du alle deine Geräte verloren haben solltest" "Wiederherstellung einrichten" "Wiederherstellung einrichten" diff --git a/features/home/impl/src/main/res/values-fr/translations.xml b/features/home/impl/src/main/res/values-fr/translations.xml index 11f842916f..d54e8fb943 100644 --- a/features/home/impl/src/main/res/values-fr/translations.xml +++ b/features/home/impl/src/main/res/values-fr/translations.xml @@ -3,6 +3,8 @@ "Désactivez l’optimisation de la batterie pour cette application afin de vous assurer que toutes les notifications sont reçues." "Désactiver l’optimisation" "Ils vous manque des notifications?" + "Le son des notifications a été modifié: plus clair, plus court et moins perturbateur." + "Nous avons rafraîchi les sons" "Générez une nouvelle clé de récupération qui peut être utilisée pour restaurer l’historique de vos messages chiffrés au cas où vous perdriez l’accès à vos appareils." "Configurer la sauvegarde" "Configurer la récupération" diff --git a/features/home/impl/src/main/res/values-nb/translations.xml b/features/home/impl/src/main/res/values-nb/translations.xml index 172ca33485..42216442cb 100644 --- a/features/home/impl/src/main/res/values-nb/translations.xml +++ b/features/home/impl/src/main/res/values-nb/translations.xml @@ -3,6 +3,8 @@ "Deaktiver batterioptimalisering for denne appen for å sikre at alle varsler mottas." "Deaktiver optimalisering" "Kommer ikke varslene frem?" + "Varslingssignalet ditt er oppdatert – tydeligere, raskere og mindre forstyrrende." + "Vi har oppdatert lydene dine" "Gjenopprett din kryptografiske identitet og meldingshistorikk med en gjenopprettingsnøkkel hvis du har mistet alle dine brukte enheter." "Konfigurer gjenoppretting" "Konfigurer gjenoppretting for å beskytte kontoen din" diff --git a/features/home/impl/src/main/res/values-ro/translations.xml b/features/home/impl/src/main/res/values-ro/translations.xml index 36a32bf089..e4a80b4fb7 100644 --- a/features/home/impl/src/main/res/values-ro/translations.xml +++ b/features/home/impl/src/main/res/values-ro/translations.xml @@ -3,6 +3,8 @@ "Dezactivați optimizarea bateriei pentru această aplicație, pentru a vă asigura că toate notificările sunt primite." "Dezactivați optimizarea" "Nu primiți notificări?" + "Sunetul pentru notificări a fost actualizat — mai clar, mai rapid și mai puțin perturbatoar." + "Am reîmprospătat sunetele" "Recuperați-vă identitatea criptografică și mesajele anterioare cu o cheie de recuperare dacă ați pierdut toate dispozitivele existente." "Configurați recuperarea" "Configurați recuperarea pentru a vă proteja contul" diff --git a/features/home/impl/src/main/res/values-ru/translations.xml b/features/home/impl/src/main/res/values-ru/translations.xml index 975e48a160..0f77d56db4 100644 --- a/features/home/impl/src/main/res/values-ru/translations.xml +++ b/features/home/impl/src/main/res/values-ru/translations.xml @@ -3,6 +3,8 @@ "Выключите оптимизацию расхода батареи, чтобы убедиться, что все уведомления будут поступать." "Выключить оптимизацию" "Уведомления не поступают?" + "Ваши уведомления были обновлены — теперь они понятнее, быстрее и менее отвлекающие." + "Мы обновили ваши звуки" "Создайте новый ключ восстановления, который можно использовать для восстановления зашифрованной истории сообщений в случае потери доступа к своим устройствам." "Настроить восстановление" "Для защиты вашего аккаунта рекомендуется настроить восстановление" diff --git a/features/home/impl/src/main/res/values/localazy.xml b/features/home/impl/src/main/res/values/localazy.xml index e6e09b5e47..80a263a179 100644 --- a/features/home/impl/src/main/res/values/localazy.xml +++ b/features/home/impl/src/main/res/values/localazy.xml @@ -3,6 +3,8 @@ "Disable battery optimisation for this app, to make sure all notifications are received." "Disable optimisation" "Notifications not arriving?" + "Your notification ping has been updated—clearer, quicker, and less disruptive." + "We’ve refreshed your sounds" "Recover your cryptographic identity and message history with a recovery key if you have lost all your existing devices." "Set up recovery" "Set up recovery to protect your account" diff --git a/features/joinroom/impl/src/main/res/values-da/translations.xml b/features/joinroom/impl/src/main/res/values-da/translations.xml index ff85698b23..ac1cd26191 100644 --- a/features/joinroom/impl/src/main/res/values-da/translations.xml +++ b/features/joinroom/impl/src/main/res/values-da/translations.xml @@ -1,7 +1,7 @@ - "Du blev spærret fra dette rum af %1$s." - "Du blev spærret fra dette rum" + "Du blev spærret af %1$s." + "Du blev spærret" "Årsag: %1$s." "Annuller anmodning" "Ja, annullér" @@ -11,12 +11,12 @@ "Er du sikker på, at du vil afvise invitationen til at deltage i dette rum? Dette forhindrer også %1$s i at kontakte dig eller invitere dig til andre rum." "Afvis invitation og blokér" "Afvis og blokér" - "Deltagelse i rummet fejlede." - "Dette rum er enten kun for gæster, eller der kan være sat begrænsninger for adgangen på klyngeniveau." - "Glem dette rum" - "Du har brug for en invitation for at deltage i dette rum" + "Deltagelse fejlede." + "Du skal enten inviteres til at deltage, eller der kan være adgangsbegrænsninger." + "Glem" + "Du har brug for en invitation for at deltage" "Inviteret af" - "Deltag i rummet" + "Deltag" "Du skal muligvis være inviteret eller være medlem af en klynge for at deltage." "Send anmodning om at deltage" "Tilladte tegn %1$d af %2$d" diff --git a/features/joinroom/impl/src/main/res/values-de/translations.xml b/features/joinroom/impl/src/main/res/values-de/translations.xml index 7971edbeff..c6d97d6fcb 100644 --- a/features/joinroom/impl/src/main/res/values-de/translations.xml +++ b/features/joinroom/impl/src/main/res/values-de/translations.xml @@ -1,7 +1,7 @@ - "Du wurdest von %1$s für diesen Chat gesperrt." - "Du wurdest für diesen Chat gesperrt" + "Du wurdest von %1$s gesperrt." + "Du wurdest gesperrt" "Grund:%1$s." "Anfrage abbrechen" "Ja, abbrechen" @@ -11,12 +11,12 @@ "Bist du sicher, dass du die Einladung zu diesem Chat ablehnen möchtest? Dadurch wird auch jede weitere Kontaktaufnahme oder Chat Einladung von %1$s blockiert." "Einladung ablehnen & Nutzer blockieren" "Ablehnen und blockieren" - "Der Beitritt zum Chat schlug fehl." - "Dieser Chat ist entweder nur auf Einladung zugänglich oder es gibt andere Zugangsbeschränkungen durch Spaces." - "Vergiss diesen Chat" - "Du benötigst eine Einladung, um diesem Chat beizutreten" + "Beitritt fehlgeschlagen" + "Du musst entweder eingeladen werden, um beizutreten, oder es gibt möglicherweise Zugriffsbeschränkungen." + "Vergessen" + "Du benötigst eine Einladung, um beizutreten" "Eingeladen von" - "Chat beitreten" + "Beitreten" "Möglicherweise musst du eingeladen werden oder ein Mitglied eines Spaces sein, um beitreten zu können." "Anklopfen" "%1$d von %2$d erlaubte Zeichen" diff --git a/features/joinroom/impl/src/main/res/values-nb/translations.xml b/features/joinroom/impl/src/main/res/values-nb/translations.xml index f494bfa4f8..5c4873bc57 100644 --- a/features/joinroom/impl/src/main/res/values-nb/translations.xml +++ b/features/joinroom/impl/src/main/res/values-nb/translations.xml @@ -1,7 +1,7 @@ - "Du ble utestengt fra dette rommet av %1$s." - "Du ble utestengt fra dette rommet" + "Du ble utestengt av %1$s." + "Du ble utestengt" "Årsak: %1$s." "Avbryt forespørsel" "Ja, avbryt" @@ -11,12 +11,12 @@ "Er du sikker på at du vil avslå invitasjonen til å bli med i dette rommet? Dette vil også forhindre %1$s fra å kontakte deg eller invitere deg til rom." "Avslå invitasjon og blokker" "Avslå og blokker" - "Å bli med i rommet mislyktes." - "Dette rommet er enten kun for inviterte, eller det kan være begrensninger for tilgang på områdenivå." - "Glem dette rommet" - "Du trenger en invitasjon for å bli med i dette rommet" + "Kunne ikke bli med" + "Du må enten bli invitert til å bli med, eller så kan det være begrensninger på tilgangen." + "Glem" + "Du trenger en invitasjon for å bli med" "Invitert av" - "Bli med i rommet" + "Bli med" "Du må kanskje bli invitert eller være medlem av et område for å bli med." "Send forespørsel om å bli med" "Tillatte tegn %1$d av %2$d" diff --git a/features/joinroom/impl/src/main/res/values-ro/translations.xml b/features/joinroom/impl/src/main/res/values-ro/translations.xml index 2246013403..8326ce06bf 100644 --- a/features/joinroom/impl/src/main/res/values-ro/translations.xml +++ b/features/joinroom/impl/src/main/res/values-ro/translations.xml @@ -1,6 +1,6 @@ - "Ai fost exclus din această cameră de către %1$s." + "Ați fost exclus din această cameră de către %1$s." "Ați fost exclus din această cameră." "Motiv: %1$s." "Anulați cererea" @@ -16,7 +16,7 @@ "Uitați această cameră" "Aveți nevoie de o invitație pentru a vă alătura acestei camere." "Invitat de" - "Alăturați-vă camerei" + "Alăturați-vă" "Este posibil să fie necesar să fiți invitat sau să fiți membru al unui spațiu pentru a vă alătura." "Trimiteți o cerere de alăturare" "Caractere permise %1$d din %2$d" diff --git a/features/joinroom/impl/src/main/res/values/localazy.xml b/features/joinroom/impl/src/main/res/values/localazy.xml index 3d6a319aa6..0e1787fc0b 100644 --- a/features/joinroom/impl/src/main/res/values/localazy.xml +++ b/features/joinroom/impl/src/main/res/values/localazy.xml @@ -1,7 +1,7 @@ - "You were banned from this room by %1$s." - "You were banned from this room" + "You were banned by %1$s." + "You were banned" "Reason: %1$s." "Cancel request" "Yes, cancel" @@ -11,12 +11,12 @@ "Are you sure you want to decline the invite to join this room? This will also prevent %1$s from contacting you or inviting you to rooms." "Decline invite & block" "Decline and block" - "Joining the room failed." - "This room is either invite-only or there might be restrictions to access at space level." - "Forget this room" - "You need an invite in order to join this room" + "Joining failed" + "You either need to be invited to join or there might be restrictions to access." + "Forget" + "You need an invite in order to join" "Invited by" - "Join room" + "Join" "You may need to be invited or be a member of a space in order to join." "Send request to join" "Allowed characters %1$d of %2$d" diff --git a/features/preferences/impl/src/main/res/values-da/translations.xml b/features/preferences/impl/src/main/res/values-da/translations.xml index acf9fe4087..f258fb0952 100644 --- a/features/preferences/impl/src/main/res/values-da/translations.xml +++ b/features/preferences/impl/src/main/res/values-da/translations.xml @@ -10,6 +10,7 @@ "Ugyldig URL, sørg for at inkludere protokollen (http/https) og den korrekte adresse." "Skjul avatarer i anmodninger om invitation til rum" "Skjul forhåndsvisning af medier i tidslinjen" + "Laboratorier" "Upload fotos og videoer hurtigere, og reducér dataforbrug" "Optimér mediekvaliteten" "Moderation og sikkerhed" @@ -43,6 +44,11 @@ "Kan ikke opdatere profilen" "Redigér profil" "Opdaterer profil…" + "Aktivér svar-tråde" + "Appen genstarter for at anvende denne ændring." + "Prøv vores nyeste idéer under udvikling. Disse funktioner er ikke færdige; de ​​kan være ustabile og kan ændre sig." + "Er du i humør til at eksperimentere?" + "Laboratorier" "Yderligere indstillinger" "Lyd- og videoopkald" "Uoverensstemmelse i konfigurationen" diff --git a/features/preferences/impl/src/main/res/values-de/translations.xml b/features/preferences/impl/src/main/res/values-de/translations.xml index 4072207fb4..c3722ec88c 100644 --- a/features/preferences/impl/src/main/res/values-de/translations.xml +++ b/features/preferences/impl/src/main/res/values-de/translations.xml @@ -10,6 +10,7 @@ "Ungültige URL, bitte gib das Protokoll (http/https) und die richtige Adresse an." "Avatare in Chateinladungen ausblenden" "Medienvorschau im Nachrichtenverlauf ausblenden" + "Labs" "Lade Fotos und Videos schneller hoch und reduziere den Datenverbrauch" "Optimiere die Medienqualität" "Moderation und Sicherheit" @@ -43,6 +44,11 @@ "Profil kann nicht aktualisiert werden" "Profil bearbeiten" "Profil wird aktualisiert…" + "Thread-Antworten aktivieren" + "Die App wird neu gestartet, um diese Änderung zu übernehmen." + "Probier unsere neuesten Ideen in der Entwicklung aus. Diese Funktionen sind noch nicht fertiggestellt; sie können instabil sein und sich noch ändern." + "Entdeckungsfreudig?" + "Labs" "Zusätzliche Einstellungen" "Audio- und Videoanrufe" "Konfiguration stimmt nicht überein" diff --git a/features/preferences/impl/src/main/res/values-fr/translations.xml b/features/preferences/impl/src/main/res/values-fr/translations.xml index dbb0b13326..19cc8f464a 100644 --- a/features/preferences/impl/src/main/res/values-fr/translations.xml +++ b/features/preferences/impl/src/main/res/values-fr/translations.xml @@ -10,6 +10,7 @@ "URL invalide, assurez-vous d’inclure le protocol (http/https) et l’adresse correcte." "Masquer les avatars des salons dans les invitations" "Masquer les aperçus des médias dans les discussions" + "Expérimental" "Téléchargez des photos et des vidéos plus rapidement et réduisez la consommation de données" "Optimisez la qualité des médias" "Modération et sécurité" @@ -43,6 +44,10 @@ "Impossible de mettre à jour le profil" "Modifier le profil" "Mise à jour du profil…" + "Activez les fils de discussion." + "Découvrez nos dernières idées en cours de développement. Ces fonctionnalités ne sont pas encore finalisées; elles peuvent être instables et évoluer." + "Envie d’expérimenter?" + "Expérimental" "Réglages supplémentaires" "Appels audio et vidéo" "Incompatibilité de configuration" diff --git a/features/preferences/impl/src/main/res/values-nb/translations.xml b/features/preferences/impl/src/main/res/values-nb/translations.xml index f30bbc9e90..90ec12a1a1 100644 --- a/features/preferences/impl/src/main/res/values-nb/translations.xml +++ b/features/preferences/impl/src/main/res/values-nb/translations.xml @@ -10,6 +10,7 @@ "Ugyldig URL. Pass på at du inkluderer protokollen (http/https) og riktig adresse." "Skjul avatarer i invitasjonsforespørsler til rom" "Skjul forhåndsvisninger av medier på tidslinjen" + "Prøvefunksjoner" "Last opp bilder og videoer raskere og reduser databruken" "Optimaliser mediekvaliteten" "Moderasjon og sikkerhet" @@ -43,6 +44,11 @@ "Kan ikke oppdatere profilen" "Rediger profil" "Oppdaterer profilen…" + "Aktiver trådsvar" + "Appen vil starte på nytt for å implementere denne endringen." + "Prøv ut våre nyeste ideer under utvikling. Disse funksjonene er ikke ferdig utviklet; de kan være ustabile og kan endres." + "Lyst til å prøve noe nytt?" + "Prøvefunksjoner" "Ytterligere innstillinger" "Lyd- og videosamtaler" "Uoverensstemmelse i konfigurasjonen" diff --git a/features/preferences/impl/src/main/res/values-ro/translations.xml b/features/preferences/impl/src/main/res/values-ro/translations.xml index 5977771ee6..6f8e41c5b9 100644 --- a/features/preferences/impl/src/main/res/values-ro/translations.xml +++ b/features/preferences/impl/src/main/res/values-ro/translations.xml @@ -10,6 +10,7 @@ "URL invalid, vă rugăm să vă asigurați că includeți protocolul (http/https) și adresa corectă." "Ascundeți avatarele din invitațiile pentru camere" "Ascundeți previzualizările media în lista de mesaje" + "Laboratoare" "Încărcați fotografii și videoclipuri mai rapid și reduceți consumul de date" "Optimizați calitatea media" "Moderare și siguranță" @@ -43,6 +44,11 @@ "Nu s-a putut actualiza profilul" "Editați profilul" "Se actualizează profilul…" + "Activați răspunsurile în fir" + "Aplicația va reporni pentru a aplica această modificare." + "Încercați cele mai noi idei în curs de dezvoltare. Aceste funcții nu sunt finalizate; pot fi instabile și pot suferi modificări." + "Doriți experiențe noi?" + "Laboratoare" "Setări adiționale" "Apeluri audio și video" "Nepotrivire de configurație" diff --git a/features/preferences/impl/src/main/res/values-ru/translations.xml b/features/preferences/impl/src/main/res/values-ru/translations.xml index 72a9f75c7c..6ac5a5d03c 100644 --- a/features/preferences/impl/src/main/res/values-ru/translations.xml +++ b/features/preferences/impl/src/main/res/values-ru/translations.xml @@ -44,6 +44,10 @@ "Невозможно обновить профиль" "Редактировать профиль" "Обновление профиля…" + "Включить ответы в топике" + "Попробуйте наши последние идеи в разработке. Эти функции ещё не завершены, они могут быть нестабильны и могут измениться." + "Хотите попробовать?" + "Лаборатория" "Дополнительные параметры" "Аудио и видео звонки" "Несоответствие конфигурации" diff --git a/features/rageshake/impl/src/main/res/values-nb/translations.xml b/features/rageshake/impl/src/main/res/values-nb/translations.xml index 277effef92..4fa4d0a653 100644 --- a/features/rageshake/impl/src/main/res/values-nb/translations.xml +++ b/features/rageshake/impl/src/main/res/values-nb/translations.xml @@ -14,5 +14,6 @@ "Send skjermbilde" "Logger vil bli inkludert i meldingen din, for å sikre at alt fungerer som det skal. For å sende meldingen uten logger, slå av denne innstillingen." "%1$s krasjet sist gang den ble brukt. Vil du dele en krasjrapport med oss?" + "Hvis du har problemer med varsler, kan det å laste opp varslingsinnstillingene hjelpe oss med å finne den underliggende årsaken." "Vis logger" diff --git a/features/space/impl/src/main/res/values-da/translations.xml b/features/space/impl/src/main/res/values-da/translations.xml index ec7da700a9..7953f32e99 100644 --- a/features/space/impl/src/main/res/values-da/translations.xml +++ b/features/space/impl/src/main/res/values-da/translations.xml @@ -6,5 +6,8 @@ "Forlad %1$d rum og klynger" "Vælg de rum, du vil forlade, som du ikke er den eneste administrator for:" + "Du skal tildele en anden administrator til denne klynge, før du kan forlade den." + "Du vil ikke blive fjernet fra følgende rum, fordi du er den eneste administrator:" "Forlad %1$s?" + "Du er den eneste administrator for %1$s" diff --git a/features/space/impl/src/main/res/values-de/translations.xml b/features/space/impl/src/main/res/values-de/translations.xml index d42e979ef1..6fd5d7c76b 100644 --- a/features/space/impl/src/main/res/values-de/translations.xml +++ b/features/space/impl/src/main/res/values-de/translations.xml @@ -6,5 +6,8 @@ "%1$d Chats und Space verlassen" "Dadurch wirst du auch aus allen Chats in diesem Space entfernt." + "Du musst einen anderen Admin für diesen Space zuweisen, bevor du ihn verlassen kannst." + "Du wirst aus den folgenden Chats nicht entfernt, weil du der einzige Admin bist:" "%1$s verlassen?" + "Du bist der einzige Administrator für %1$s" diff --git a/features/space/impl/src/main/res/values-nb/translations.xml b/features/space/impl/src/main/res/values-nb/translations.xml index e25a2ba6f0..aafe1d756f 100644 --- a/features/space/impl/src/main/res/values-nb/translations.xml +++ b/features/space/impl/src/main/res/values-nb/translations.xml @@ -1,5 +1,9 @@ + "%1$s (Admin)" "Velg rommene du vil forlate, som du ikke er den eneste administratoren for:" + "Du må tildele en annen administrator for dette området før du kan forlate det." + "Du vil ikke bli fjernet fra følgende rom fordi du er den eneste administratoren:" "Forlat %1$s?" + "Du er den eneste administratoren for %1$s" diff --git a/features/verifysession/impl/src/main/res/values-nb/translations.xml b/features/verifysession/impl/src/main/res/values-nb/translations.xml index 2696ae62f4..bec26b129e 100644 --- a/features/verifysession/impl/src/main/res/values-nb/translations.xml +++ b/features/verifysession/impl/src/main/res/values-nb/translations.xml @@ -18,6 +18,7 @@ "Sammenlign tallene" "Nå kan du lese eller sende meldinger sikkert på den andre enheten din." "Nå kan du stole på identiteten til denne brukeren når du sender eller mottar meldinger." + "Enheten er verifisert" "Skriv inn gjenopprettingsnøkkel" "Enten ble forespørselen tidsavbrutt, forespørselen ble avslått eller det var en feil i verifiseringen." "Bevis at det er deg for å få tilgang til den krypterte meldingshistorikken din." diff --git a/libraries/push/impl/src/main/res/values-da/translations.xml b/libraries/push/impl/src/main/res/values-da/translations.xml index 17893b5135..255605953b 100644 --- a/libraries/push/impl/src/main/res/values-da/translations.xml +++ b/libraries/push/impl/src/main/res/values-da/translations.xml @@ -64,7 +64,10 @@ "Blokerede brugere" "Få navnet på den aktuelle udbyder." "Ingen push-udbydere valgt." + "Nuværende push-udbyder: %1$s og nuværende distributør: %2$s. Men distributøren %3$s kan ikke findes. Måske er applikationen blevet afinstalleret?" + "Nuværende push-udbyder: %1$s, men der er ikke konfigureret nogen distributører." "Nuværende push-udbyder: %1$s." + "Nuværende push-udbyder: %1$s (%2$s)" "Nuværende push-udbyder" "Sørg for, at programmet understøtter mindst én push-udbyder." "Ingen push-udbyder understøttelse fundet." diff --git a/libraries/push/impl/src/main/res/values-de/translations.xml b/libraries/push/impl/src/main/res/values-de/translations.xml index 81e1815168..4ded5207f2 100644 --- a/libraries/push/impl/src/main/res/values-de/translations.xml +++ b/libraries/push/impl/src/main/res/values-de/translations.xml @@ -65,6 +65,7 @@ "Ermittele den Namen des aktuellen Anbieters." "Kein Dienst für Push-Benachrichtigungen ausgewählt." "Aktueller Push-Dienst: %1$s." + "Aktueller Push-Dienst: %1$s (%2$s)" "Aktueller Push-Dienst" "Stelle sicher, dass die Anwendung mindestens einen Push-Dienst hat." "Keine Unterstützung für Push-Dienst gefunden." diff --git a/libraries/push/impl/src/main/res/values-nb/translations.xml b/libraries/push/impl/src/main/res/values-nb/translations.xml index 08c327acdb..7f8cc41413 100644 --- a/libraries/push/impl/src/main/res/values-nb/translations.xml +++ b/libraries/push/impl/src/main/res/values-nb/translations.xml @@ -55,11 +55,18 @@ "Google Services" "Ingen gyldige Google Play-tjenester funnet. Det kan hende at varsler ikke fungerer som de skal." "Sjekker blokkerte brukere" + "Vis blokkerte brukere" "Ingen brukere er blokkert." + + "Du blokkerte%1$d bruker. Du vil ikke motta varsler for denne brukeren." + "Du blokkerte%1$d brukere. Du vil ikke motta varsler for disse brukerne." + "Blokkerte brukere" "Få navnet på den nåværende tilbyderen." "Ingen push-leverandører er valgt." + "Nåværende push-leverandør: %1$s, men ingen distributører er konfigurert." "Gjeldende push-leverandør: %1$s." + "Nåværende push-leverandør: %1$s (%2$s)" "Nåværende push-leverandør" "Påse at applikasjonen har minst én push-leverandør." "Ingen push-leverandører funnet." diff --git a/libraries/ui-strings/src/main/res/values-da/translations.xml b/libraries/ui-strings/src/main/res/values-da/translations.xml index d411d3d0d1..93295756b9 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -94,6 +94,7 @@ "Har du glemt din adgangskode?" "Videresend" "Gå tilbage" + "Gå til indstillinger" "Ignorér" "Invitér" "Invitér andre" @@ -110,6 +111,7 @@ "Administrer konto" "Administrer enheder" "Besked" + "Minimér" "Næste" "Nej" "Ikke nu" @@ -176,6 +178,7 @@ "Du blev logget ud af sessionen" "Udseende" "Lyd" + "Beta" "Blokerede brugere" "Bobler" "Opkald startet" @@ -225,6 +228,7 @@ "Installer APK" "Dette Matrix-ID kan ikke findes, så invitationen modtages muligvis ikke." "Forlader rummet" + "Forlader klynge" "Lyst tema" "Linje kopieret til udklipsholder" "Linket er kopieret til udklipsholderen" @@ -313,6 +317,7 @@ "Indstillinger" "Del klynge" "Delt placering" + "Delt klynge" "Logger ud" "Noget gik galt" "Vi stødte på et problem. Prøv venligst igen." diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index a5557b2b60..6528cd924f 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -94,6 +94,7 @@ "Passwort vergessen?" "Weiterleiten" "Zurück" + "Zu den Einstellungen" "Ignorieren" "Einladen" "Nutzer einladen" @@ -110,6 +111,7 @@ "Konto verwalten" "Geräte verwalten" "Nachricht" + "Minimieren" "Weiter" "Nein" "Später" @@ -176,6 +178,7 @@ "Du wurdest aus der Sitzung abgemeldet." "Erscheinungsbild" "Audio" + "Beta" "Blockierte Nutzer" "Sprechblasen" "Anruf gestartet" @@ -314,6 +317,7 @@ Grund: %1$s." "Einstellungen" "Space teilen" "Geteilter Standort" + "Gemeinsamer Space" "Abmelden" "Es ist ein Fehler aufgetreten." "Wir haben ein Problem festgestellt. Bitte versuch es erneut." diff --git a/libraries/ui-strings/src/main/res/values-fr/translations.xml b/libraries/ui-strings/src/main/res/values-fr/translations.xml index 3dce6a923c..d35d9886fa 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -94,6 +94,7 @@ "Mot de passe oublié ?" "Transférer" "Retour" + "Ouvrir les paramètres" "Ignorer" "Inviter" "Inviter des amis" @@ -177,6 +178,7 @@ "Vous avez été déconnecté de la session" "Apparence" "Audio" + "Bêta" "Utilisateurs bloqués" "Bulles" "Appel démarré" diff --git a/libraries/ui-strings/src/main/res/values-nb/translations.xml b/libraries/ui-strings/src/main/res/values-nb/translations.xml index eb2f8cc5b1..6f21f7b86c 100644 --- a/libraries/ui-strings/src/main/res/values-nb/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nb/translations.xml @@ -93,6 +93,7 @@ "Glemt passordet?" "Videresend" "Gå tilbake" + "Gå til innstillinger" "Ignorer" "Inviter" "Inviter folk" @@ -109,6 +110,7 @@ "Administrer konto" "Administrer enheter" "Melding" + "Minimer" "Neste" "Nei" "Ikke nå" @@ -175,6 +177,7 @@ "Du ble logget ut av økten" "Utseende" "Lyd" + "Beta" "Blokkerte brukere" "Bobler" "Samtale startet" @@ -189,6 +192,7 @@ "Mørk" "Dekrypteringsfeil" "Beskrivelse" + "Velg bort alle" "Alternativer for utviklere" "Enhets-ID" "Direkte chat" @@ -223,6 +227,7 @@ "Installer APK" "Finner ikke denne Matrix-IDen, så invitasjonen blir kanskje ikke mottatt." "Forlater rommet" + "Forlater området" "Lys" "Linje kopiert til utklippstavlen" "Lenke kopiert til utklippstavlen" @@ -298,6 +303,7 @@ "Sikkerhet" "Sett av" "Velg en konto" + "Velg alle" "Sendt til" "Sender…" "Kunne ikke sende" @@ -308,6 +314,7 @@ "Innstillinger" "Del område" "Delt posisjon" + "Delt område" "Logger av" "Noe gikk galt" "Vi har støtt på et problem. Vennligst prøv igjen." @@ -453,6 +460,7 @@ Er du sikker på at du vil fortsette?" "Del denne lokasjonen" "Områder du har opprettet eller blitt med i." "%1$s • %2$s" + "%1$s område" "Områder" "Meldingen ble ikke sendt fordi %1$ss verifiserte identitet er tilbakestilt." "Meldingen ble ikke sendt fordi %1$s ikke har verifisert alle enheter." diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 9fe88da203..905969debb 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -96,6 +96,7 @@ "Ați uitat parola?" "Redirecționați" "Înapoi" + "Mergeți la setări" "Ignorați" "Invitați" "Invitați prieteni" @@ -179,6 +180,7 @@ "Ați fost deconectat din sesiune." "Aspect" "Audio" + "Beta" "Utilizatori blocați" "Baloane" "A început un apel" @@ -323,6 +325,7 @@ Motiv:%1$s." "Setări" "Partajați spațiul" "Locație partajată" + "Spațiu comun" "Deconectare în curs" "Ceva nu a mers bine" "Am întâmpinat o problemă. Vă rugăm să încercați din nou." diff --git a/libraries/ui-strings/src/main/res/values-ru/translations.xml b/libraries/ui-strings/src/main/res/values-ru/translations.xml index 5773be3e1d..d8fe1367bb 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -166,8 +166,6 @@ "Да, попробуйте еще раз" "Теперь ваш сервер поддерживает новый, более быстрый протокол. Чтобы обновить его прямо сейчас, выйдите и войдите в свою учётную запись снова. Сделав это сейчас, вы сможете избежать принудительного выхода из системы при последующем удалении старого протокола." "Доступно обновление" - "Ваши уведомления были обновлены — теперь они понятнее, быстрее и менее отвлекающие." - "Мы обновили ваши звуки" "О приложении" "Политика допустимого использования" "Добавить аккаунт" @@ -433,10 +431,6 @@ "Параметры" "Удалить %1$s" "Настройки" - "Включить ответы в топике" - "Попробуйте наши последние идеи в разработке. Эти функции ещё не завершены, они могут быть нестабильны и могут измениться." - "Хотите попробовать?" - "Лаборатория" "Не удалось выбрать носитель, попробуйте еще раз." "Нажмите на сообщение и выберите “%1$s”, чтобы добавить его сюда." "Закрепите важные сообщения, чтобы их можно было легко найти" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 9b254127ee..dab9506ae5 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -166,8 +166,6 @@ "Yes, try again" "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later." "Upgrade available" - "Your notification ping has been updated—clearer, quicker, and less disruptive." - "We’ve refreshed your sounds" "About" "Acceptable use policy" "Add an account" @@ -428,11 +426,6 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" - "Enable thread replies" - "Restarting the app is required to apply changes" - "Try out our latest ideas in development. These features are not finalised; they may be unstable, may change." - "Feeling experimental?" - "Labs" "Failed selecting media, please try again." "Press on a message and choose “%1$s” to include here." "Pin important messages so that they can be easily discovered" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 3840e5f38c..82c273db2e 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -185,6 +185,7 @@ "confirm_recovery_key_banner_.*", "banner\\.set_up_recovery\\..*", "banner\\.battery_optimization\\..*", + "banner\\.new_sound\\..*", "full_screen_intent_banner_.*", "screen_migration_.*", "screen_invites_.*" From 58fca2e9e29f114fb89413044fd6db31632eea8b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 11:31:18 +0200 Subject: [PATCH 69/73] New notification sound banner --- .../components/NewNotificationSoundBanner.kt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/NewNotificationSoundBanner.kt diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/NewNotificationSoundBanner.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/NewNotificationSoundBanner.kt new file mode 100644 index 0000000000..f7516e41e8 --- /dev/null +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/NewNotificationSoundBanner.kt @@ -0,0 +1,43 @@ +/* + * 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.home.impl.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import io.element.android.features.home.impl.R +import io.element.android.libraries.designsystem.components.Announcement +import io.element.android.libraries.designsystem.components.AnnouncementType +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +internal fun NewNotificationSoundBanner( + onDismissClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Announcement( + modifier = modifier.roomListBannerPadding(), + title = stringResource(R.string.banner_new_sound_title), + description = stringResource(R.string.banner_new_sound_message), + type = AnnouncementType.Actionable( + actionText = stringResource(CommonStrings.action_ok), + onActionClick = onDismissClick, + onDismissClick = onDismissClick, + ), + ) +} + +@PreviewsDayNight +@Composable +internal fun NewNotificationSoundBannerPreview() = ElementPreview { + NewNotificationSoundBanner( + onDismissClick = {}, + ) +} From df384f6365601433283b1e5ed0e9f4e05f5a8955 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 12:16:49 +0200 Subject: [PATCH 70/73] Add isFreshInstall Boolean to allow the miration to behave in a different way for an application upgrade or a fresh install. We cannot restore the previous code which existed because of https://github.com/element-hq/element-x-android/pull/3535 --- .../migration/impl/MigrationPresenter.kt | 4 +++- .../migration/impl/migrations/AppMigration.kt | 2 +- .../impl/migrations/AppMigration01.kt | 2 +- .../impl/migrations/AppMigration02.kt | 2 +- .../impl/migrations/AppMigration03.kt | 4 ++-- .../impl/migrations/AppMigration04.kt | 2 +- .../impl/migrations/AppMigration05.kt | 2 +- .../impl/migrations/AppMigration06.kt | 2 +- .../impl/migrations/AppMigration07.kt | 2 +- .../migration/impl/MigrationPresenterTest.kt | 21 ++++++++++++------- .../impl/migrations/AppMigration01Test.kt | 2 +- .../impl/migrations/AppMigration02Test.kt | 2 +- .../impl/migrations/AppMigration03Test.kt | 2 +- .../impl/migrations/AppMigration04Test.kt | 2 +- .../impl/migrations/AppMigration05Test.kt | 4 ++-- .../impl/migrations/AppMigration06Test.kt | 4 ++-- .../impl/migrations/AppMigration07Test.kt | 2 +- 17 files changed, 35 insertions(+), 26 deletions(-) diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/MigrationPresenter.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/MigrationPresenter.kt index 7edbc5389f..d4e6d6dc37 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/MigrationPresenter.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/MigrationPresenter.kt @@ -31,6 +31,7 @@ class MigrationPresenter( ) : Presenter { private val orderedMigrations = migrations.sortedBy { it.order } private val lastMigration: Int = orderedMigrations.lastOrNull()?.order ?: 0 + private var isFreshInstall = false @Composable override fun present(): MigrationState { @@ -49,6 +50,7 @@ class MigrationPresenter( val migrationValue = migrationStoreVersion ?: return@LaunchedEffect if (migrationValue == -1) { Timber.d("Fresh install, or previous installed application did not have the migration mechanism.") + isFreshInstall = true } if (migrationValue == lastMigration) { Timber.d("Current app migration version: $migrationValue. No migration needed.") @@ -59,7 +61,7 @@ class MigrationPresenter( val nextMigration = orderedMigrations.firstOrNull { it.order > migrationValue } if (nextMigration != null) { Timber.d("Current app migration version: $migrationValue. Applying migration: ${nextMigration.order}") - nextMigration.migrate() + nextMigration.migrate(isFreshInstall) migrationStore.setApplicationMigrationVersion(nextMigration.order) } } diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration.kt index a0327e8b09..f14ec89dbe 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration.kt @@ -9,5 +9,5 @@ package io.element.android.features.migration.impl.migrations interface AppMigration { val order: Int - suspend fun migrate() + suspend fun migrate(isFreshInstall: Boolean) } diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01.kt index 048a400f6c..88fdb16b9e 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01.kt @@ -22,7 +22,7 @@ class AppMigration01( ) : AppMigration { override val order: Int = 1 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { logFilesRemover.perform() } } diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02.kt index 44f4806c65..0ba2712427 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02.kt @@ -27,7 +27,7 @@ class AppMigration02( ) : AppMigration { override val order: Int = 2 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { coroutineScope { for (session in sessionStore.getAllSessions()) { val sessionId = SessionId(session.userId) diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03.kt index 0cb3573954..e24e18a205 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03.kt @@ -21,7 +21,7 @@ class AppMigration03( ) : AppMigration { override val order: Int = 3 - override suspend fun migrate() { - migration01.migrate() + override suspend fun migrate(isFreshInstall: Boolean) { + migration01.migrate(isFreshInstall) } } diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04.kt index 8ab4921038..f1f16b7a97 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04.kt @@ -27,7 +27,7 @@ class AppMigration04( } override val order: Int = 4 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { runCatchingExceptions { context.getDatabasePath(NOTIFICATION_FILE_NAME).delete() } } } diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt index 109ff7e0b7..2a60822c5d 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt @@ -22,7 +22,7 @@ class AppMigration05( ) : AppMigration { override val order: Int = 5 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { val allSessions = sessionStore.getAllSessions() for (session in allSessions) { if (session.sessionPath.isEmpty()) { diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt index 2eb98b9e5f..be3050f919 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt @@ -25,7 +25,7 @@ class AppMigration06( ) : AppMigration { override val order: Int = 6 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { val allSessions = sessionStore.getAllSessions() for (session in allSessions) { if (session.cachePath.isEmpty()) { diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt index fe88817796..5367323b75 100644 --- a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt @@ -22,7 +22,7 @@ class AppMigration07( ) : AppMigration { override val order: Int = 7 - override suspend fun migrate() { + override suspend fun migrate(isFreshInstall: Boolean) { logFilesRemover.perform { file -> file.name.startsWith("logs-") } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/MigrationPresenterTest.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/MigrationPresenterTest.kt index 635a06f028..e5898ea0dd 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/MigrationPresenterTest.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/MigrationPresenterTest.kt @@ -15,8 +15,10 @@ import io.element.android.features.migration.impl.migrations.AppMigration import io.element.android.libraries.architecture.AsyncData import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate -import io.element.android.tests.testutils.lambda.LambdaNoParamRecorder +import io.element.android.tests.testutils.lambda.LambdaOneParamRecorder +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -48,13 +50,18 @@ class MigrationPresenterTest { assertThat(store.applicationMigrationVersion().first()).isEqualTo(migrations.maxOf { it.order }) } for (migration in migrations) { - migration.migrateLambda.assertions().isCalledOnce() + migration.migrateLambda.assertions().isCalledOnce().with(value(true)) } } @Test fun `present - no migration should occurs if ApplicationMigrationVersion is the last one`() = runTest { - val migrations = (1..10).map { FakeAppMigration(it) } + val migrations = (1..10).map { + FakeAppMigration( + order = it, + migrateLambda = lambdaRecorder { lambdaError() }, + ) + } val store = InMemoryMigrationStore(migrations.maxOf { it.order }) val presenter = createPresenter( migrationStore = store, @@ -90,7 +97,7 @@ class MigrationPresenterTest { consumeItemsUntilPredicate { it.migrationAction is AsyncData.Success } assertThat(store.applicationMigrationVersion().first()).isEqualTo(migrations.maxOf { it.order }) for (migration in migrations) { - migration.migrateLambda.assertions().isCalledOnce() + migration.migrateLambda.assertions().isCalledOnce().with(value(false)) } } } @@ -106,9 +113,9 @@ private fun createPresenter( private class FakeAppMigration( override val order: Int, - val migrateLambda: LambdaNoParamRecorder = lambdaRecorder { -> }, + val migrateLambda: LambdaOneParamRecorder = lambdaRecorder { }, ) : AppMigration { - override suspend fun migrate() { - migrateLambda() + override suspend fun migrate(isFreshInstall: Boolean) { + migrateLambda(isFreshInstall) } } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01Test.kt index 580be7d705..6e1b663e3c 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration01Test.kt @@ -17,7 +17,7 @@ class AppMigration01Test { val logsFileRemover = FakeLogFilesRemover() val migration = AppMigration01(logsFileRemover) - migration.migrate() + migration.migrate(true) logsFileRemover.performLambda.assertions().isCalledOnce() } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02Test.kt index fb7dbf5281..08c10160b8 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration02Test.kt @@ -30,7 +30,7 @@ class AppMigration02Test { ) val migration = AppMigration02(sessionStore = sessionStore, sessionPreferenceStoreFactory = sessionPreferencesStoreFactory) - migration.migrate() + migration.migrate(true) // We got the session preferences store sessionPreferencesStoreFactory.getLambda.assertions().isCalledOnce() diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03Test.kt index e4911faaa5..0f4db78aa2 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration03Test.kt @@ -17,7 +17,7 @@ class AppMigration03Test { val logsFileRemover = FakeLogFilesRemover() val migration = AppMigration03(migration01 = AppMigration01(logsFileRemover)) - migration.migrate() + migration.migrate(true) logsFileRemover.performLambda.assertions().isCalledOnce() } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04Test.kt index f272dadc22..68cbfde689 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration04Test.kt @@ -28,7 +28,7 @@ class AppMigration04Test { val migration = AppMigration04(context) - migration.migrate() + migration.migrate(true) // Check that the file has been deleted assertThat(file.exists()).isFalse() diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05Test.kt index af71905635..ff5b8cd40a 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05Test.kt @@ -27,7 +27,7 @@ class AppMigration05Test { ) ) val migration = AppMigration05(sessionStore = sessionStore, baseDirectory = File("/a/path")) - migration.migrate() + migration.migrate(true) val storedData = sessionStore.getSession(A_SESSION_ID.value)!! assertThat(storedData.sessionPath).isEqualTo("/a/path/${A_SESSION_ID.value.replace(':', '_')}") } @@ -43,7 +43,7 @@ class AppMigration05Test { ) ) val migration = AppMigration05(sessionStore = sessionStore, baseDirectory = File("/a/path")) - migration.migrate() + migration.migrate(true) val storedData = sessionStore.getSession(A_SESSION_ID.value)!! assertThat(storedData.sessionPath).isEqualTo("/a/path/existing") } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06Test.kt index 095085cd17..e7e15ba821 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06Test.kt @@ -28,7 +28,7 @@ class AppMigration06Test { ) ) val migration = AppMigration06(sessionStore = sessionStore, cacheDirectory = File("/a/path/cache")) - migration.migrate() + migration.migrate(true) val storedData = sessionStore.getSession(A_SESSION_ID.value)!! assertThat(storedData.cachePath).isEqualTo("/a/path/cache/AN_ID") } @@ -44,7 +44,7 @@ class AppMigration06Test { ) ) val migration = AppMigration05(sessionStore = sessionStore, baseDirectory = File("/a/path/cache")) - migration.migrate() + migration.migrate(true) val storedData = sessionStore.getSession(A_SESSION_ID.value)!! assertThat(storedData.cachePath).isEqualTo("/a/path/existing") } diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt index a375ef8563..a2575b32df 100644 --- a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt @@ -24,7 +24,7 @@ class AppMigration07Test { } val logsFileRemover = FakeLogFilesRemover(performLambda = performLambda) val migration = AppMigration07(logsFileRemover) - migration.migrate() + migration.migrate(true) performLambda.assertions().isCalledOnce() } } From 98637b8fc556e6ae415892e1bd4f04c7fb346c24 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 12:20:24 +0200 Subject: [PATCH 71/73] Show new notification sound banner logic --- .../impl/components/RoomListContentView.kt | 6 ++++ .../roomlist/RoomListContentStateProvider.kt | 5 +++ .../home/impl/roomlist/RoomListEvents.kt | 1 + .../home/impl/roomlist/RoomListPresenter.kt | 15 ++++++-- .../home/impl/roomlist/RoomListState.kt | 1 + .../impl/roomlist/RoomListPresenterTest.kt | 33 ++++++++++++++++++ .../impl/migrations/AppMigration08.kt | 30 ++++++++++++++++ .../impl/migrations/AppMigration08Test.kt | 34 +++++++++++++++++++ .../api/store/AppPreferencesStore.kt | 3 ++ .../impl/store/DefaultAppPreferencesStore.kt | 14 ++++++++ .../test/InMemoryAppPreferencesStore.kt | 10 ++++++ 11 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08.kt create mode 100644 features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08Test.kt diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomListContentView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomListContentView.kt index 2845a79b8e..34d036b204 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomListContentView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomListContentView.kt @@ -251,6 +251,12 @@ private fun RoomsViewList( item { BatteryOptimizationBanner(state = state.batteryOptimizationState) } + } else if (state.showNewNotificationSoundBanner) { + item { + NewNotificationSoundBanner( + onDismissClick = { updatedEventSink(RoomListEvents.DismissNewNotificationSoundBanner) }, + ) + } } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListContentStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListContentStateProvider.kt index a421c239cb..0cc2fd6282 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListContentStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListContentStateProvider.kt @@ -26,17 +26,22 @@ open class RoomListContentStateProvider : PreviewParameterProvider = aRoomListRoomSummaryList(), fullScreenIntentPermissionsState: FullScreenIntentPermissionsState = aFullScreenIntentPermissionsState(), batteryOptimizationState: BatteryOptimizationState = aBatteryOptimizationState(), seenRoomInvites: Set = emptySet(), ) = RoomListContentState.Rooms( securityBannerState = securityBannerState, + showNewNotificationSoundBanner = showNewNotificationSoundBanner, fullScreenIntentPermissionsState = fullScreenIntentPermissionsState, batteryOptimizationState = batteryOptimizationState, summaries = summaries, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListEvents.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListEvents.kt index 02df2cac35..52da613be7 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListEvents.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListEvents.kt @@ -14,6 +14,7 @@ sealed interface RoomListEvents { data class UpdateVisibleRange(val range: IntRange) : RoomListEvents data object DismissRequestVerificationPrompt : RoomListEvents data object DismissBanner : RoomListEvents + data object DismissNewNotificationSoundBanner : RoomListEvents data object ToggleSearchResults : RoomListEvents data class ShowContextMenu(val roomSummary: RoomListRoomSummary) : RoomListEvents diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt index 7b51e4797e..72a666a124 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt @@ -98,6 +98,7 @@ class RoomListPresenter( } var securityBannerDismissed by rememberSaveable { mutableStateOf(false) } + val showNewNotificationSoundBanner by appPreferencesStore.showNewNotificationSoundBanner().collectAsState(false) // Avatar indicator val hideInvitesAvatar by client.rememberHideInvitesAvatar() @@ -112,6 +113,9 @@ class RoomListPresenter( } RoomListEvents.DismissRequestVerificationPrompt -> securityBannerDismissed = true RoomListEvents.DismissBanner -> securityBannerDismissed = true + RoomListEvents.DismissNewNotificationSoundBanner -> coroutineScope.launch { + appPreferencesStore.setShowNewNotificationSoundBanner(false) + } RoomListEvents.ToggleSearchResults -> searchState.eventSink(RoomListSearchEvents.ToggleSearchVisibility) is RoomListEvents.ShowContextMenu -> { coroutineScope.showContextMenu(event, contextMenu) @@ -141,7 +145,10 @@ class RoomListPresenter( } } - val contentState = roomListContentState(securityBannerDismissed) + val contentState = roomListContentState( + securityBannerDismissed, + showNewNotificationSoundBanner, + ) val canReportRoom by produceState(false) { value = client.canReportRoom() } @@ -197,6 +204,7 @@ class RoomListPresenter( @Composable private fun roomListContentState( securityBannerDismissed: Boolean, + showNewNotificationSoundBanner: Boolean, ): RoomListContentState { val roomSummaries by produceState(initialValue = AsyncData.Loading()) { roomListDataSource.allRooms.collect { value = AsyncData.Success(it) } @@ -215,11 +223,14 @@ class RoomListPresenter( val seenRoomInvites by remember { seenInvitesStore.seenRoomIds() }.collectAsState(emptySet()) val securityBannerState by rememberSecurityBannerState(securityBannerDismissed) return when { - showEmpty -> RoomListContentState.Empty(securityBannerState = securityBannerState) + showEmpty -> RoomListContentState.Empty( + securityBannerState = securityBannerState, + ) showSkeleton -> RoomListContentState.Skeleton(count = 16) else -> { RoomListContentState.Rooms( securityBannerState = securityBannerState, + showNewNotificationSoundBanner = showNewNotificationSoundBanner, fullScreenIntentPermissionsState = fullScreenIntentPermissionsPresenter.present(), batteryOptimizationState = batteryOptimizationPresenter.present(), summaries = roomSummaries.dataOrNull().orEmpty().toPersistentList(), diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListState.kt index 4a301f0897..80cd6394e8 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListState.kt @@ -69,6 +69,7 @@ sealed interface RoomListContentState { val securityBannerState: SecurityBannerState, val fullScreenIntentPermissionsState: FullScreenIntentPermissionsState, val batteryOptimizationState: BatteryOptimizationState, + val showNewNotificationSoundBanner: Boolean, val summaries: ImmutableList, val seenRoomInvites: ImmutableSet, ) : RoomListContentState diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index bde004cf82..041c43dab0 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -75,6 +75,7 @@ import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runTest @@ -593,6 +594,38 @@ class RoomListPresenterTest { } } + @Test + fun `present - notification sound banner`() = runTest { + val subscribeToVisibleRoomsLambda = lambdaRecorder { _: List -> } + val roomListService = FakeRoomListService(subscribeToVisibleRoomsLambda = subscribeToVisibleRoomsLambda) + val matrixClient = FakeMatrixClient( + roomListService = roomListService, + ) + val roomSummary = aRoomSummary( + currentUserMembership = CurrentUserMembership.INVITED + ) + roomListService.postAllRoomsLoadingState(RoomList.LoadingState.Loaded(1)) + roomListService.postAllRooms(listOf(roomSummary)) + val store = InMemoryAppPreferencesStore() + val presenter = createRoomListPresenter( + client = matrixClient, + appPreferencesStore = store, + ) + presenter.test { + assertThat(store.showNewNotificationSoundBanner().first()).isFalse() + skipItems(1) + val state = awaitItem() + assertThat(state.contentAsRooms().showNewNotificationSoundBanner).isFalse() + store.setShowNewNotificationSoundBanner(true) + assertThat(store.showNewNotificationSoundBanner().first()).isTrue() + assertThat(awaitItem().contentAsRooms().showNewNotificationSoundBanner).isTrue() + state.eventSink(RoomListEvents.DismissNewNotificationSoundBanner) + assertThat(awaitItem().contentAsRooms().showNewNotificationSoundBanner).isFalse() + // Ensure store has been updated + assertThat(store.showNewNotificationSoundBanner().first()).isFalse() + } + } + private fun TestScope.createRoomListPresenter( client: MatrixClient = FakeMatrixClient(), leaveRoomState: LeaveRoomState = aLeaveRoomState(), diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08.kt new file mode 100644 index 0000000000..df1a508a6d --- /dev/null +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08.kt @@ -0,0 +1,30 @@ +/* + * 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.migration.impl.migrations + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesIntoSet +import dev.zacsweers.metro.Inject +import io.element.android.libraries.preferences.api.store.AppPreferencesStore + +/** + * Ensure the new notification sound banner is displayed, but only on application upgrade. + */ +@ContributesIntoSet(AppScope::class) +@Inject +class AppMigration08( + private val appPreferencesStore: AppPreferencesStore, +) : AppMigration { + override val order: Int = 8 + + override suspend fun migrate(isFreshInstall: Boolean) { + if (!isFreshInstall) { + appPreferencesStore.setShowNewNotificationSoundBanner(true) + } + } +} diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08Test.kt new file mode 100644 index 0000000000..f908a10bcc --- /dev/null +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration08Test.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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.migration.impl.migrations + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class AppMigration08Test { + @Test + fun `migration on fresh install should not modify the store`() = runTest { + val store = InMemoryAppPreferencesStore() + assertThat(store.showNewNotificationSoundBanner().first()).isFalse() + val migration = AppMigration08(store) + migration.migrate(isFreshInstall = true) + assertThat(store.showNewNotificationSoundBanner().first()).isFalse() + } + + @Test + fun `migration on upgrade should modify the store`() = runTest { + val store = InMemoryAppPreferencesStore() + assertThat(store.showNewNotificationSoundBanner().first()).isFalse() + val migration = AppMigration08(store) + migration.migrate(isFreshInstall = false) + assertThat(store.showNewNotificationSoundBanner().first()).isTrue() + } +} diff --git a/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt b/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt index 7e47785088..18d7d4f092 100644 --- a/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt +++ b/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt @@ -37,5 +37,8 @@ interface AppPreferencesStore { suspend fun setTracingLogPacks(targets: Set) fun getTracingLogPacksFlow(): Flow> + suspend fun setShowNewNotificationSoundBanner(show: Boolean) + fun showNewNotificationSoundBanner(): Flow + suspend fun reset() } diff --git a/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt b/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt index b3890a8a7d..984503e673 100644 --- a/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt +++ b/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt @@ -30,6 +30,7 @@ private val hideInviteAvatarsKey = booleanPreferencesKey("hideInviteAvatars") private val timelineMediaPreviewValueKey = stringPreferencesKey("timelineMediaPreviewValue") private val logLevelKey = stringPreferencesKey("logLevel") private val traceLogPacksKey = stringPreferencesKey("traceLogPacks") +private val showNewNotificationSoundBannerKey = booleanPreferencesKey("showNewNotificationSoundBanner") @ContributesBinding(AppScope::class) @Inject @@ -145,6 +146,19 @@ class DefaultAppPreferencesStore( } } + override suspend fun setShowNewNotificationSoundBanner(show: Boolean) { + store.edit { prefs -> + prefs[showNewNotificationSoundBannerKey] = show + } + } + + override fun showNewNotificationSoundBanner(): Flow { + return store.data.map { prefs -> + // Default is false, but a migration will set it to true on application upgrade (see AppMigration08) + prefs[showNewNotificationSoundBannerKey] ?: false + } + } + override suspend fun reset() { store.edit { it.clear() } } diff --git a/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt b/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt index d0ee298a66..a601eb6b1d 100644 --- a/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt +++ b/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt @@ -22,6 +22,7 @@ class InMemoryAppPreferencesStore( theme: String? = null, logLevel: LogLevel = LogLevel.INFO, traceLockPacks: Set = emptySet(), + showNewNotificationSoundBanner: Boolean = false, ) : AppPreferencesStore { private val isDeveloperModeEnabled = MutableStateFlow(isDeveloperModeEnabled) private val customElementCallBaseUrl = MutableStateFlow(customElementCallBaseUrl) @@ -30,6 +31,7 @@ class InMemoryAppPreferencesStore( private val tracingLogPacks = MutableStateFlow(traceLockPacks) private val hideInviteAvatars = MutableStateFlow(hideInviteAvatars) private val timelineMediaPreviewValue = MutableStateFlow(timelineMediaPreviewValue) + private val showNewNotificationSoundBanner = MutableStateFlow(showNewNotificationSoundBanner) override suspend fun setDeveloperModeEnabled(enabled: Boolean) { isDeveloperModeEnabled.value = enabled @@ -91,6 +93,14 @@ class InMemoryAppPreferencesStore( return tracingLogPacks } + override suspend fun setShowNewNotificationSoundBanner(show: Boolean) { + showNewNotificationSoundBanner.value = show + } + + override fun showNewNotificationSoundBanner(): Flow { + return showNewNotificationSoundBanner + } + override suspend fun reset() { // No op } From 1532a83ab1d1163189324a6a78675bc4561e3915 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 7 Oct 2025 14:09:53 +0000 Subject: [PATCH 72/73] Update screenshots --- ...me.impl.components_NewNotificationSoundBanner_Day_0_en.png | 3 +++ ....impl.components_NewNotificationSoundBanner_Night_0_en.png | 3 +++ ...ures.home.impl.components_RoomListContentView_Day_5_en.png | 3 +++ ...es.home.impl.components_RoomListContentView_Night_5_en.png | 3 +++ .../images/features.joinroom.impl_JoinRoomView_Day_10_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_14_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_15_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_16_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_1_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_2_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_3_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_4_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_5_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Day_9_en.png | 4 ++-- .../features.joinroom.impl_JoinRoomView_Night_10_en.png | 4 ++-- .../features.joinroom.impl_JoinRoomView_Night_14_en.png | 4 ++-- .../features.joinroom.impl_JoinRoomView_Night_15_en.png | 4 ++-- .../features.joinroom.impl_JoinRoomView_Night_16_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_1_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_2_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_3_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_4_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_5_en.png | 4 ++-- .../images/features.joinroom.impl_JoinRoomView_Night_9_en.png | 4 ++-- 24 files changed, 52 insertions(+), 40 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Day_0_en.png new file mode 100644 index 0000000000..dbfe7bfa4a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:367bec41d3cf5e7d0e369a4610584c5a11ca7a69fe26b794290c49027de465a4 +size 23221 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Night_0_en.png new file mode 100644 index 0000000000..0d2f51d4c1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_NewNotificationSoundBanner_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e666d80cb22b979a075ee9b749a36c4f9a4874149ba4d736d745c8311f6e0e85 +size 22563 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png new file mode 100644 index 0000000000..e1efabe407 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf85a6a94ee3eed576e91c7a3a55e45571dff4a6dce1f6c6bbd22845fb01a76b +size 59896 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png new file mode 100644 index 0000000000..70f3c084fe --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4646f1622c26a45208fa8ad59c9f531c1794e1874e31e50942f459bf3be3de2 +size 58927 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png index 4f172d6a06..7475ebf250 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7fdd74d6df903a0cedfbfc2f30430b5802e4f0bc7b2711e20ae47d297066b056 -size 40297 +oid sha256:c8ed797426703ce250ebb4e0cd0d6753e0581a7751fc35654d12ebe4c0746a9b +size 39351 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_14_en.png index 0834071308..578db9b288 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37ac3a032e758c4abf9ac8a87e887c7e015f2d35160d59a7e263963300bd0941 -size 31558 +oid sha256:f892ffadc2999b904be4fc72b0345524a53699386265ff446ee981f815e51ed0 +size 30111 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_15_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_15_en.png index 330bd7edc7..8c7da8b54c 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44b9c4608696c6a690e7f00f661b3cb55d03826b11569b6e8ce0a48f9754dd39 -size 38547 +oid sha256:44f1bc19ce7f2db1d2e9ce5a0018d48848c63af21847ec238d08791999df8401 +size 34559 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_16_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_16_en.png index e9ce885cd8..1549fc3041 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f92065e3de67f39ce27ae3e321f59fa2d18b5927752dc760450ec275935b1959 -size 43405 +oid sha256:4b05cd6be3be2571745310c89448bce1562fa191a061549cd3ad0936656933d8 +size 42456 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_1_en.png index c127d5b02f..0c2e9f7f03 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:919101bfd215af97a098bdfae4980445bd1d0560f96fe9ce13a870e2d8817fff -size 34247 +oid sha256:680f7a4fd4a992e70aef33628faed82c8238109860fe87b91a417d1b880f0a4d +size 33258 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_2_en.png index a902aef055..33023589e6 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f9707b754041c871c408e12613faa186fa4f4f760ca793caf20c62bae07246b -size 32021 +oid sha256:62a10762a1eb986d6f870d82fd9f5b10803e5178ce4192c4ae6cc17889f44c14 +size 31021 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_3_en.png index 16ac399dbf..78c6876524 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ad9105ca2659f51b16b41f9317812590f38adb8431a64a139bb47f54fdf9eff -size 29754 +oid sha256:8f592039e3dcf2036bbfc7e644eddd717bb9c2fac2715077b8744a96d5e8ce94 +size 28712 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_4_en.png index 78b8500823..12dee69df9 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04180611d2a959d07bbbd051c4386f6428d841c5ea74e197a80149370db76e04 -size 41830 +oid sha256:2a707c7e9e4a1c91d12733a4002c914feb5365dad1e5fda77b4b3fd862d98916 +size 39587 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_5_en.png index 644110ef6d..0e57f43ea3 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c4a828b9aa4e4963e3cb39e6f65f82ff5e595fdccb4dc5b48db532eeac1fb00 -size 31388 +oid sha256:018a813fbd3d3bbae4627fa9acbbbde709d83d67b7292ce02c3cd170572184d6 +size 30602 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png index 593cc05c7a..fd13827148 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d0bd66c54a98b59a6b4325735eb34ab9bef7c6807c4fc0e33044ee396e46b14 -size 36344 +oid sha256:19484bb21efbedc60478192da648d035334fb0adf7f6efda0977a3a25e3b6696 +size 35394 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png index edc2a732b6..4e05331ad7 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5a6da57cc5659ba3f3705cba41fd23c7628ba2477fcfc427b8e26bde37ed812 -size 39960 +oid sha256:27c86e8f5c4a00cb13b024bd0cb1375f04d547d03dd35459c4a0853106f1a3c9 +size 39079 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_14_en.png index 867ef2ea72..f5fe9ed256 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f47c18fda5c4839e1098955f57c4a3e5b9856203c6a84c31903aa5e0b2da46b -size 30971 +oid sha256:6977342388cd3702e94d7b233dcf89ee2b0698ff1f39323c0520a9b88128a3fd +size 29622 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_15_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_15_en.png index 40257d2267..bcfe430ad5 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:112286f6a18865db2333a68cb804e930eb873bb04596bada2f825e2223b4f537 -size 37362 +oid sha256:f6993298eb428c9f79a7b837c633b20c69a8170f179bf47af1f967ca2eb28f66 +size 33788 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_16_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_16_en.png index abc81a0d58..d0a42e7563 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff86f906357d0bf611bfc9cd235e66e0247dd7bb66903cb0e5730224d5dc897c -size 43008 +oid sha256:374318e250e1b813025f56ee7121e05905421c6c5657e228bce58f60da9729f2 +size 42137 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_1_en.png index b480466344..27790717cd 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc849f3158de5cd3cdc64a57e613f3b3a5cd70794e7984d7cfa1f8f425184592 -size 33440 +oid sha256:498e344123c195dadb96125bb2fad6ff7c8647dc1205adbb1e2068820e861631 +size 32516 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_2_en.png index 9869f158e6..129a92851b 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed211c9bc258185de6ea4cc414fd214f256ad1649c26a8a28f25fd1b29c34783 -size 31630 +oid sha256:d14358f97b6a7267deae81f0ff721fcde2acf63c5baff718beb94c41c9afa022 +size 30696 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_3_en.png index 42619d6321..8a6464958c 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a88ffdfd4259a2e85b3a8375591eab3b0f12e927eb83f9c6820995acf44d79e -size 29607 +oid sha256:77f4e76bc68f099d5f28f811c004dbc48a5da17edb0576dc76761cbe85ee9bb0 +size 28629 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_4_en.png index 1b95755ca6..8093435a66 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7fbe20a3d4e0c3706ce81c1f52c65ff4f749b0afd6bdd3efb4100ee1019afc51 -size 40580 +oid sha256:a7fc4c0f8964f6cde35dc18ad39cc89249e14af35a10ab7a060e213b622f008b +size 38446 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_5_en.png index 0211928122..0ceacc4260 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cff1f0a8a34cfd4eb55487540a02c70e629d7f6123355c95380498817053eb78 -size 29575 +oid sha256:1151f42b6fdb810a78dae144be8cdc1a97f4d0153c8690cbf2756b75308aaa13 +size 28869 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png index 5e4e84c276..ecf3010c75 100644 --- a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:029fd9d3e150b6a8d52b4d348ccdbbb661b0009b7065b9530f4e7f168fc6ee78 -size 35965 +oid sha256:b2e279977cd66e1be4159c788a70b8caca9cf32d7b428b0a2407105aabe9a405 +size 35083 From c059e407497b054ed1a2fa1e590f77a0224a255c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 7 Oct 2025 16:49:51 +0200 Subject: [PATCH 73/73] Fix compilation issue in tests. --- .../impl/notifications/channels/NotificationChannelsTest.kt | 2 ++ .../factories/DefaultNotificationCreatorTest.kt | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt index a6b8bc9985..b93bbcaf15 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt @@ -18,6 +18,7 @@ import io.mockk.verify import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @@ -66,5 +67,6 @@ class NotificationChannelsTest { ) = DefaultNotificationChannels( notificationManager = notificationManager, stringProvider = FakeStringProvider(), + context = RuntimeEnvironment.getApplication(), ) } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt index 5fd1b6386e..7786fb261e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt @@ -332,5 +332,9 @@ fun createNotificationCreator( fun createNotificationChannels(): NotificationChannels { val context = RuntimeEnvironment.getApplication() - return DefaultNotificationChannels(NotificationManagerCompat.from(context), FakeStringProvider("")) + return DefaultNotificationChannels( + notificationManager = NotificationManagerCompat.from(context), + stringProvider = FakeStringProvider(""), + context = context, + ) }