From 5b6866435048817dc108d11bb1e5f26e6b715f49 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 14:59:49 +0100 Subject: [PATCH 001/103] Expose liveLocationSharing methods from sdk --- .../libraries/matrix/api/room/JoinedRoom.kt | 27 ++++++++++++++++ .../api/room/location/LiveLocationShare.kt | 24 ++++++++++++++ .../matrix/impl/room/JoinedRustRoom.kt | 31 +++++++++++++++++++ .../room/location/LiveLocationShareMapper.kt | 21 +++++++++++++ .../matrix/test/room/FakeJoinedRoom.kt | 21 +++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationShare.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/LiveLocationShareMapper.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/JoinedRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/JoinedRoom.kt index b804bdf46d..808f37c7c9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/JoinedRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/JoinedRoom.kt @@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.knock.KnockRequest +import io.element.android.libraries.matrix.api.room.location.LiveLocationShare import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -182,4 +183,30 @@ interface JoinedRoom : BaseRoom { * Subscribe to a [Flow] of [SendQueueUpdate] related to this room. */ fun subscribeToSendQueueUpdates(): Flow + + /** + * Subscribe to live location shares in this room. + * @return Flow of list of active live location shares. + */ + fun subscribeToLiveLocationShares(): Flow> + + /** + * Start sharing live location in this room. + * @param durationMillis How long to share location (in milliseconds). + * @return Result indicating success or failure. + */ + suspend fun startLiveLocationShare(durationMillis: Long): Result + + /** + * Stop sharing live location in this room. + * @return Result indicating success or failure. + */ + suspend fun stopLiveLocationShare(): Result + + /** + * Send a live location update while a live location share is active. + * @param geoUri The geo URI (e.g., "geo:51.5074,-0.1278"). + * @return Result indicating success or failure. + */ + suspend fun sendLiveLocation(geoUri: String): Result } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationShare.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationShare.kt new file mode 100644 index 0000000000..7e841639bd --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationShare.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Element Creations 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.room.location + +import io.element.android.libraries.matrix.api.core.UserId + +/** + * Represents a live location share from a user in a room. + */ +data class LiveLocationShare( + /** The user who is sharing their location. */ + val userId: UserId, + /** The last known geo URI (e.g., "geo:51.5074,-0.1278"). */ + val lastGeoUri: String, + /** The timestamp of the last location update. */ + val lastTimestamp: Long, + /** Whether the live location share is still active. */ + val isLive: Boolean, +) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt index dded213d4c..4f9568df7c 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.room.SendQueueUpdate import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.knock.KnockRequest +import io.element.android.libraries.matrix.api.room.location.LiveLocationShare import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.roomNotificationSettings @@ -42,6 +43,7 @@ import io.element.android.libraries.matrix.impl.mapper.map import io.element.android.libraries.matrix.impl.room.history.map import io.element.android.libraries.matrix.impl.room.join.map import io.element.android.libraries.matrix.impl.room.knock.RustKnockRequest +import io.element.android.libraries.matrix.impl.room.location.map import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher import io.element.android.libraries.matrix.impl.roomdirectory.map import io.element.android.libraries.matrix.impl.timeline.RustTimeline @@ -66,6 +68,7 @@ import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.DateDividerMode import org.matrix.rustcomponents.sdk.IdentityStatusChangeListener import org.matrix.rustcomponents.sdk.KnockRequestsListener +import org.matrix.rustcomponents.sdk.LiveLocationShareListener import org.matrix.rustcomponents.sdk.RoomMessageEventMessageType import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate import org.matrix.rustcomponents.sdk.SendQueueListener @@ -500,6 +503,34 @@ class JoinedRustRoom( } } + override fun subscribeToLiveLocationShares(): Flow> { + return mxCallbackFlow { + innerRoom.subscribeToLiveLocationShares(object : LiveLocationShareListener { + override fun call(liveLocationShares: List) { + trySend(liveLocationShares.map { it.map() }) + } + }) + } + } + + override suspend fun startLiveLocationShare(durationMillis: Long): Result = withContext(roomDispatcher) { + runCatchingExceptions { + innerRoom.startLiveLocationShare(durationMillis.toULong()) + } + } + + override suspend fun stopLiveLocationShare(): Result = withContext(roomDispatcher) { + runCatchingExceptions { + innerRoom.stopLiveLocationShare() + } + } + + override suspend fun sendLiveLocation(geoUri: String): Result = withContext(roomDispatcher) { + runCatchingExceptions { + innerRoom.sendLiveLocation(geoUri) + } + } + override fun close() = destroy() override fun destroy() { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/LiveLocationShareMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/LiveLocationShareMapper.kt new file mode 100644 index 0000000000..3b80c1c61f --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/LiveLocationShareMapper.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Element Creations 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.room.location + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.location.LiveLocationShare +import org.matrix.rustcomponents.sdk.LiveLocationShare as RustLiveLocationShare + +fun RustLiveLocationShare.map(): LiveLocationShare { + return LiveLocationShare( + userId = UserId(userId), + lastGeoUri = lastLocation.location.geoUri, + lastTimestamp = lastLocation.ts.toLong(), + isLive = isLive, + ) +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeJoinedRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeJoinedRoom.kt index 9c97e7787b..a4580334e4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeJoinedRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeJoinedRoom.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.room.SendQueueUpdate import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.knock.KnockRequest +import io.element.android.libraries.matrix.api.room.location.LiveLocationShare import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -84,6 +85,10 @@ class FakeJoinedRoom( private val enableEncryptionResult: () -> Result = { lambdaError() }, private val updateJoinRuleResult: (JoinRule) -> Result = { lambdaError() }, private val setSendQueueEnabledResult: (Boolean) -> Unit = { _: Boolean -> }, + private val liveLocationSharesFlow: Flow> = MutableStateFlow(emptyList()), + private val startLiveLocationShareResult: (Long) -> Result = { lambdaError() }, + private val stopLiveLocationShareResult: () -> Result = { lambdaError() }, + private val sendLiveLocationResult: (String) -> Result = { lambdaError() }, ) : JoinedRoom, BaseRoom by baseRoom { private val sendQueueUpdates = MutableSharedFlow(extraBufferCapacity = 10) @@ -227,6 +232,22 @@ class FakeJoinedRoom( return sendQueueUpdates } + override fun subscribeToLiveLocationShares(): Flow> { + return liveLocationSharesFlow + } + + override suspend fun startLiveLocationShare(durationMillis: Long): Result = simulateLongTask { + startLiveLocationShareResult(durationMillis) + } + + override suspend fun stopLiveLocationShare(): Result = simulateLongTask { + stopLiveLocationShareResult() + } + + override suspend fun sendLiveLocation(geoUri: String): Result = simulateLongTask { + sendLiveLocationResult(geoUri) + } + private suspend fun simulateSendMediaProgress(progressCallback: ProgressCallback?) { progressCallbackValues.forEach { (current, total) -> progressCallback?.onProgress(current, total) From 1f5a628b131e74a98ee41d247f37c7974e3aa379 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 15:04:19 +0100 Subject: [PATCH 002/103] Add LiveLocationSharing ff --- .../android/libraries/featureflag/api/FeatureFlags.kt | 7 +++++++ 1 file changed, 7 insertions(+) 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 3b47726b80..12c18955f4 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 @@ -147,4 +147,11 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), + LiveLocationSharing( + key = "feature.liveLocationSharing", + title = "Live location sharing", + description = "Allow sharing live location in rooms.", + defaultValue = { false }, + isFinished = false, + ), } From 8c64f704cb86216d999ed54e96f6c96972f038bb Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 15:20:21 +0100 Subject: [PATCH 003/103] Rename send location to share location --- ...tryPoint.kt => ShareLocationEntryPoint.kt} | 4 +- .../impl/send/SendLocationStateProvider.kt | 58 ------- .../DefaultShareLocationEntryPoint.kt} | 10 +- .../ShareLocationEvents.kt} | 18 +-- .../ShareLocationNode.kt} | 8 +- .../ShareLocationPresenter.kt} | 64 ++++---- .../ShareLocationState.kt} | 6 +- .../impl/share/ShareLocationStateProvider.kt | 58 +++++++ .../ShareLocationView.kt} | 46 +++--- .../DefaultShareLocationEntryPointTest.kt} | 14 +- .../ShareLocationPresenterTest.kt} | 146 +++++++++--------- ...oint.kt => FakeShareLocationEntryPoint.kt} | 4 +- .../messages/impl/MessagesFlowNode.kt | 6 +- .../impl/DefaultMessagesEntryPointTest.kt | 4 +- 14 files changed, 223 insertions(+), 223 deletions(-) rename features/location/api/src/main/kotlin/io/element/android/features/location/api/{SendLocationEntryPoint.kt => ShareLocationEntryPoint.kt} (89%) delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationStateProvider.kt rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/DefaultSendLocationEntryPoint.kt => share/DefaultShareLocationEntryPoint.kt} (70%) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/SendLocationEvents.kt => share/ShareLocationEvents.kt} (54%) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/SendLocationNode.kt => share/ShareLocationNode.kt} (91%) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/SendLocationPresenter.kt => share/ShareLocationPresenter.kt} (73%) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/SendLocationState.kt => share/ShareLocationState.kt} (82%) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/{send/SendLocationView.kt => share/ShareLocationView.kt} (82%) rename features/location/impl/src/test/kotlin/io/element/android/features/location/impl/{send/DefaultSendLocationEntryPointTest.kt => share/DefaultShareLocationEntryPointTest.kt} (84%) rename features/location/impl/src/test/kotlin/io/element/android/features/location/impl/{send/SendLocationPresenterTest.kt => share/ShareLocationPresenterTest.kt} (77%) rename features/location/test/src/main/kotlin/io/element/android/features/location/test/{FakeSendLocationEntryPoint.kt => FakeShareLocationEntryPoint.kt} (83%) diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/SendLocationEntryPoint.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShareLocationEntryPoint.kt similarity index 89% rename from features/location/api/src/main/kotlin/io/element/android/features/location/api/SendLocationEntryPoint.kt rename to features/location/api/src/main/kotlin/io/element/android/features/location/api/ShareLocationEntryPoint.kt index 48816b2bb4..62a81662ce 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/SendLocationEntryPoint.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShareLocationEntryPoint.kt @@ -14,11 +14,11 @@ import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.matrix.api.timeline.Timeline /** - * The "Send location" screen. + * The "Share location" screen. * * Allows a user to share a location message within a room. */ -interface SendLocationEntryPoint : FeatureEntryPoint { +interface ShareLocationEntryPoint : FeatureEntryPoint { fun createNode( parentNode: Node, buildContext: BuildContext, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationStateProvider.kt deleted file mode 100644 index 238201cbec..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationStateProvider.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * 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.features.location.impl.send - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider - -private const val APP_NAME = "ApplicationName" - -class SendLocationStateProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - aSendLocationState( - permissionDialog = SendLocationState.Dialog.None, - mode = SendLocationState.Mode.PinLocation, - hasLocationPermission = false, - ), - aSendLocationState( - permissionDialog = SendLocationState.Dialog.PermissionDenied, - mode = SendLocationState.Mode.PinLocation, - hasLocationPermission = false, - ), - aSendLocationState( - permissionDialog = SendLocationState.Dialog.PermissionRationale, - mode = SendLocationState.Mode.PinLocation, - hasLocationPermission = false, - ), - aSendLocationState( - permissionDialog = SendLocationState.Dialog.None, - mode = SendLocationState.Mode.PinLocation, - hasLocationPermission = true, - ), - aSendLocationState( - permissionDialog = SendLocationState.Dialog.None, - mode = SendLocationState.Mode.SenderLocation, - hasLocationPermission = true, - ), - ) -} - -private fun aSendLocationState( - permissionDialog: SendLocationState.Dialog, - mode: SendLocationState.Mode, - hasLocationPermission: Boolean, -): SendLocationState { - return SendLocationState( - permissionDialog = permissionDialog, - mode = mode, - hasLocationPermission = hasLocationPermission, - appName = APP_NAME, - eventSink = {} - ) -} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPoint.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPoint.kt similarity index 70% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPoint.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPoint.kt index 56399f7e9d..e077453ad9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPoint.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPoint.kt @@ -6,26 +6,26 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import io.element.android.features.location.api.SendLocationEntryPoint +import io.element.android.features.location.api.ShareLocationEntryPoint import io.element.android.libraries.architecture.createNode import io.element.android.libraries.matrix.api.timeline.Timeline @ContributesBinding(AppScope::class) -class DefaultSendLocationEntryPoint : SendLocationEntryPoint { +class DefaultShareLocationEntryPoint : ShareLocationEntryPoint { override fun createNode( parentNode: Node, buildContext: BuildContext, timelineMode: Timeline.Mode, ): Node { - return parentNode.createNode( + return parentNode.createNode( buildContext = buildContext, - plugins = listOf(SendLocationNode.Inputs(timelineMode)) + plugins = listOf(ShareLocationNode.Inputs(timelineMode)) ) } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt similarity index 54% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationEvents.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt index 0d266eefc7..93b75d8e38 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationEvents.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt @@ -6,15 +6,15 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import io.element.android.features.location.api.Location -sealed interface SendLocationEvents { - data class SendLocation( +sealed interface ShareLocationEvents { + data class ShareLocation( val cameraPosition: CameraPosition, val location: Location?, - ) : SendLocationEvents { + ) : ShareLocationEvents { data class CameraPosition( val lat: Double, val lon: Double, @@ -22,9 +22,9 @@ sealed interface SendLocationEvents { ) } - data object SwitchToMyLocationMode : SendLocationEvents - data object SwitchToPinLocationMode : SendLocationEvents - data object DismissDialog : SendLocationEvents - data object RequestPermissions : SendLocationEvents - data object OpenAppSettings : SendLocationEvents + data object SwitchToMyLocationMode : ShareLocationEvents + data object SwitchToPinLocationMode : ShareLocationEvents + data object DismissDialog : ShareLocationEvents + data object RequestPermissions : ShareLocationEvents + data object OpenAppSettings : ShareLocationEvents } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationNode.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationNode.kt similarity index 91% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationNode.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationNode.kt index 2184b52b44..0b61ff0df8 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationNode.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationNode.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -26,10 +26,10 @@ import io.element.android.services.analytics.api.AnalyticsService @ContributesNode(RoomScope::class) @AssistedInject -class SendLocationNode( +class ShareLocationNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenterFactory: SendLocationPresenter.Factory, + presenterFactory: ShareLocationPresenter.Factory, analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { data class Inputs( @@ -48,7 +48,7 @@ class SendLocationNode( @Composable override fun View(modifier: Modifier) { - SendLocationView( + ShareLocationView( state = presenter.present(), modifier = modifier, navigateUp = ::navigateUp, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt similarity index 73% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index b753820e55..5b2b7ebc25 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -38,7 +38,7 @@ import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.launch @AssistedInject -class SendLocationPresenter( +class ShareLocationPresenter( permissionsPresenterFactory: PermissionsPresenter.Factory, private val room: JoinedRoom, @Assisted private val timelineMode: Timeline.Mode, @@ -46,60 +46,60 @@ class SendLocationPresenter( private val messageComposerContext: MessageComposerContext, private val locationActions: LocationActions, private val buildMeta: BuildMeta, -) : Presenter { +) : Presenter { @AssistedFactory fun interface Factory { - fun create(timelineMode: Timeline.Mode): SendLocationPresenter + fun create(timelineMode: Timeline.Mode): ShareLocationPresenter } private val permissionsPresenter = permissionsPresenterFactory.create(MapDefaults.permissions) @Composable - override fun present(): SendLocationState { + override fun present(): ShareLocationState { val permissionsState: PermissionsState = permissionsPresenter.present() - var mode: SendLocationState.Mode by remember { + var mode: ShareLocationState.Mode by remember { mutableStateOf( if (permissionsState.isAnyGranted) { - SendLocationState.Mode.SenderLocation + ShareLocationState.Mode.SenderLocation } else { - SendLocationState.Mode.PinLocation + ShareLocationState.Mode.PinLocation } ) } val appName by remember { derivedStateOf { buildMeta.applicationName } } - var permissionDialog: SendLocationState.Dialog by remember { - mutableStateOf(SendLocationState.Dialog.None) + var permissionDialog: ShareLocationState.Dialog by remember { + mutableStateOf(ShareLocationState.Dialog.None) } val scope = rememberCoroutineScope() LaunchedEffect(permissionsState.permissions) { if (permissionsState.isAnyGranted) { - mode = SendLocationState.Mode.SenderLocation - permissionDialog = SendLocationState.Dialog.None + mode = ShareLocationState.Mode.SenderLocation + permissionDialog = ShareLocationState.Dialog.None } } - fun handleEvent(event: SendLocationEvents) { + fun handleEvent(event: ShareLocationEvents) { when (event) { - is SendLocationEvents.SendLocation -> scope.launch { - sendLocation(event, mode) + is ShareLocationEvents.ShareLocation -> scope.launch { + shareLocation(event, mode) } - SendLocationEvents.SwitchToMyLocationMode -> when { - permissionsState.isAnyGranted -> mode = SendLocationState.Mode.SenderLocation - permissionsState.shouldShowRationale -> permissionDialog = SendLocationState.Dialog.PermissionRationale - else -> permissionDialog = SendLocationState.Dialog.PermissionDenied + ShareLocationEvents.SwitchToMyLocationMode -> when { + permissionsState.isAnyGranted -> mode = ShareLocationState.Mode.SenderLocation + permissionsState.shouldShowRationale -> permissionDialog = ShareLocationState.Dialog.PermissionRationale + else -> permissionDialog = ShareLocationState.Dialog.PermissionDenied } - SendLocationEvents.SwitchToPinLocationMode -> mode = SendLocationState.Mode.PinLocation - SendLocationEvents.DismissDialog -> permissionDialog = SendLocationState.Dialog.None - SendLocationEvents.OpenAppSettings -> { + ShareLocationEvents.SwitchToPinLocationMode -> mode = ShareLocationState.Mode.PinLocation + ShareLocationEvents.DismissDialog -> permissionDialog = ShareLocationState.Dialog.None + ShareLocationEvents.OpenAppSettings -> { locationActions.openSettings() - permissionDialog = SendLocationState.Dialog.None + permissionDialog = ShareLocationState.Dialog.None } - SendLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) + ShareLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) } } - return SendLocationState( + return ShareLocationState( permissionDialog = permissionDialog, mode = mode, hasLocationPermission = permissionsState.isAnyGranted, @@ -108,14 +108,14 @@ class SendLocationPresenter( ) } - private suspend fun sendLocation( - event: SendLocationEvents.SendLocation, - mode: SendLocationState.Mode, + private suspend fun shareLocation( + event: ShareLocationEvents.ShareLocation, + mode: ShareLocationState.Mode, ) { val replyMode = messageComposerContext.composerMode as? MessageComposerMode.Reply val inReplyToEventId = replyMode?.eventId when (mode) { - SendLocationState.Mode.PinLocation -> { + ShareLocationState.Mode.PinLocation -> { val geoUri = event.cameraPosition.toGeoUri() getTimeline().flatMap { it.sendLocation( @@ -136,7 +136,7 @@ class SendLocationPresenter( ) ) } - SendLocationState.Mode.SenderLocation -> { + ShareLocationState.Mode.SenderLocation -> { val geoUri = event.toGeoUri() getTimeline().flatMap { it.sendLocation( @@ -168,8 +168,8 @@ class SendLocationPresenter( } } -private fun SendLocationEvents.SendLocation.toGeoUri(): String = location?.toGeoUri() ?: cameraPosition.toGeoUri() +private fun ShareLocationEvents.ShareLocation.toGeoUri(): String = location?.toGeoUri() ?: cameraPosition.toGeoUri() -private fun SendLocationEvents.SendLocation.CameraPosition.toGeoUri(): String = "geo:$lat,$lon" +private fun ShareLocationEvents.ShareLocation.CameraPosition.toGeoUri(): String = "geo:$lat,$lon" private fun generateBody(uri: String): String = "Location was shared at $uri" diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt similarity index 82% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationState.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 4ca84c47a5..14975f1646 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -6,14 +6,14 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share -data class SendLocationState( +data class ShareLocationState( val permissionDialog: Dialog, val mode: Mode, val hasLocationPermission: Boolean, val appName: String, - val eventSink: (SendLocationEvents) -> Unit, + val eventSink: (ShareLocationEvents) -> Unit, ) { sealed interface Mode { data object SenderLocation : Mode diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt new file mode 100644 index 0000000000..df49881975 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * 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.features.location.impl.share + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +private const val APP_NAME = "ApplicationName" + +class ShareLocationStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.None, + mode = ShareLocationState.Mode.PinLocation, + hasLocationPermission = false, + ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.PermissionDenied, + mode = ShareLocationState.Mode.PinLocation, + hasLocationPermission = false, + ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.PermissionRationale, + mode = ShareLocationState.Mode.PinLocation, + hasLocationPermission = false, + ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.None, + mode = ShareLocationState.Mode.PinLocation, + hasLocationPermission = true, + ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.None, + mode = ShareLocationState.Mode.SenderLocation, + hasLocationPermission = true, + ), + ) +} + +private fun aShareLocationState( + permissionDialog: ShareLocationState.Dialog, + mode: ShareLocationState.Mode, + hasLocationPermission: Boolean, +): ShareLocationState { + return ShareLocationState( + permissionDialog = permissionDialog, + mode = mode, + hasLocationPermission = hasLocationPermission, + appName = APP_NAME, + eventSink = {} + ) +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt similarity index 82% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 452a4aa8ae..1c9e85c82b 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -56,25 +56,25 @@ import org.maplibre.android.camera.CameraPosition @OptIn(ExperimentalMaterial3Api::class) @Composable -fun SendLocationView( - state: SendLocationState, +fun ShareLocationView( + state: ShareLocationState, navigateUp: () -> Unit, modifier: Modifier = Modifier, ) { LaunchedEffect(Unit) { - state.eventSink(SendLocationEvents.RequestPermissions) + state.eventSink(ShareLocationEvents.RequestPermissions) } when (state.permissionDialog) { - SendLocationState.Dialog.None -> Unit - SendLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( - onContinue = { state.eventSink(SendLocationEvents.OpenAppSettings) }, - onDismiss = { state.eventSink(SendLocationEvents.DismissDialog) }, + ShareLocationState.Dialog.None -> Unit + ShareLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( + onContinue = { state.eventSink(ShareLocationEvents.OpenAppSettings) }, + onDismiss = { state.eventSink(ShareLocationEvents.DismissDialog) }, appName = state.appName, ) - SendLocationState.Dialog.PermissionRationale -> PermissionRationaleDialog( - onContinue = { state.eventSink(SendLocationEvents.RequestPermissions) }, - onDismiss = { state.eventSink(SendLocationEvents.DismissDialog) }, + ShareLocationState.Dialog.PermissionRationale -> PermissionRationaleDialog( + onContinue = { state.eventSink(ShareLocationEvents.RequestPermissions) }, + onDismiss = { state.eventSink(ShareLocationEvents.DismissDialog) }, appName = state.appName, ) } @@ -85,10 +85,10 @@ fun SendLocationView( LaunchedEffect(state.mode) { when (state.mode) { - SendLocationState.Mode.PinLocation -> { + ShareLocationState.Mode.PinLocation -> { cameraPositionState.cameraMode = CameraMode.NONE } - SendLocationState.Mode.SenderLocation -> { + ShareLocationState.Mode.SenderLocation -> { cameraPositionState.position = CameraPosition.Builder() .zoom(MapDefaults.DEFAULT_ZOOM) .build() @@ -99,7 +99,7 @@ fun SendLocationView( LaunchedEffect(cameraPositionState.isMoving) { if (cameraPositionState.cameraMoveStartedReason == CameraMoveStartedReason.GESTURE) { - state.eventSink(SendLocationEvents.SwitchToPinLocationMode) + state.eventSink(ShareLocationEvents.SwitchToPinLocationMode) } } @@ -114,8 +114,8 @@ fun SendLocationView( Text( stringResource( when (state.mode) { - SendLocationState.Mode.PinLocation -> CommonStrings.screen_share_this_location_action - SendLocationState.Mode.SenderLocation -> CommonStrings.screen_share_my_location_action + ShareLocationState.Mode.PinLocation -> CommonStrings.screen_share_this_location_action + ShareLocationState.Mode.SenderLocation -> CommonStrings.screen_share_my_location_action } ) ) @@ -125,8 +125,8 @@ fun SendLocationView( enabled = cameraPositionState.position.target != null ) { state.eventSink( - SendLocationEvents.SendLocation( - cameraPosition = SendLocationEvents.SendLocation.CameraPosition( + ShareLocationEvents.ShareLocation( + cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( lat = cameraPositionState.position.target!!.latitude, lon = cameraPositionState.position.target!!.longitude, zoom = cameraPositionState.position.zoom, @@ -190,8 +190,8 @@ fun SendLocationView( modifier = Modifier.centerBottomEdge(this), ) LocationFloatingActionButton( - isMapCenteredOnUser = state.mode == SendLocationState.Mode.SenderLocation, - onClick = { state.eventSink(SendLocationEvents.SwitchToMyLocationMode) }, + isMapCenteredOnUser = state.mode == ShareLocationState.Mode.SenderLocation, + onClick = { state.eventSink(ShareLocationEvents.SwitchToMyLocationMode) }, modifier = Modifier .align(Alignment.BottomEnd) .padding(end = 18.dp, bottom = 72.dp + navBarPadding), @@ -202,10 +202,10 @@ fun SendLocationView( @PreviewsDayNight @Composable -internal fun SendLocationViewPreview( - @PreviewParameter(SendLocationStateProvider::class) state: SendLocationState +internal fun ShareLocationViewPreview( + @PreviewParameter(ShareLocationStateProvider::class) state: ShareLocationState ) = ElementPreview { - SendLocationView( + ShareLocationView( state = state, navigateUp = {}, ) diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPointTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt similarity index 84% rename from features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPointTest.kt rename to features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt index a90afd5a9d..b6161b3a9c 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/DefaultSendLocationEntryPointTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.bumble.appyx.core.modality.BuildContext @@ -22,19 +22,19 @@ import io.element.android.tests.testutils.node.TestParentNode import org.junit.Rule import org.junit.Test -class DefaultSendLocationEntryPointTest { +class DefaultShareLocationEntryPointTest { @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @Test fun `test node builder`() { - val entryPoint = DefaultSendLocationEntryPoint() + val entryPoint = DefaultShareLocationEntryPoint() val parentNode = TestParentNode.create { buildContext, plugins -> - SendLocationNode( + ShareLocationNode( buildContext = buildContext, plugins = plugins, presenterFactory = { timelineMode: Timeline.Mode -> - SendLocationPresenter( + ShareLocationPresenter( permissionsPresenterFactory = { FakePermissionsPresenter() }, room = FakeJoinedRoom(), timelineMode = timelineMode, @@ -53,7 +53,7 @@ class DefaultSendLocationEntryPointTest { buildContext = BuildContext.root(null), timelineMode = timelineMode, ) - assertThat(result).isInstanceOf(SendLocationNode::class.java) - assertThat(result.plugins).contains(SendLocationNode.Inputs(timelineMode)) + assertThat(result).isInstanceOf(ShareLocationNode::class.java) + assertThat(result.plugins).contains(ShareLocationNode.Inputs(timelineMode)) } } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt similarity index 77% rename from features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt rename to features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 23ab3847cd..ead3fb2fe0 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.location.impl.send +package io.element.android.features.location.impl.share import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow @@ -40,7 +40,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test -class SendLocationPresenterTest { +class ShareLocationPresenterTest { @get:Rule val warmUpRule = WarmUpRule() @@ -50,9 +50,9 @@ class SendLocationPresenterTest { private val fakeLocationActions = FakeLocationActions() private val fakeBuildMeta = aBuildMeta(applicationName = "app name") - private fun createSendLocationPresenter( + private fun createShareLocationPresenter( joinedRoom: JoinedRoom = FakeJoinedRoom(), - ): SendLocationPresenter = SendLocationPresenter( + ): ShareLocationPresenter = ShareLocationPresenter( permissionsPresenterFactory = object : PermissionsPresenter.Factory { override fun create(permissions: List): PermissionsPresenter = fakePermissionsPresenter }, @@ -66,7 +66,7 @@ class SendLocationPresenterTest { @Test fun `initial state with permissions granted`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.AllGranted, @@ -75,25 +75,25 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(SendLocationState.Mode.SenderLocation) + assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode - initialState.eventSink(SendLocationEvents.SwitchToPinLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToPinLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isTrue() } } @Test fun `initial state with permissions partially granted`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.SomeGranted, @@ -102,25 +102,25 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(SendLocationState.Mode.SenderLocation) + assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode - initialState.eventSink(SendLocationEvents.SwitchToPinLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToPinLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isTrue() } } @Test fun `initial state with permissions denied`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -129,25 +129,25 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.PermissionDenied) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() } } @Test fun `initial state with permissions denied once`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -156,25 +156,25 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() } } @Test fun `rationale dialog dismiss`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -183,30 +183,30 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - myLocationState.eventSink(SendLocationEvents.DismissDialog) + myLocationState.eventSink(ShareLocationEvents.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(dialogDismissedState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(dialogDismissedState.hasLocationPermission).isFalse() } } @Test fun `rationale dialog continue`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -215,27 +215,27 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Continue the dialog sends permission request to the permissions presenter - myLocationState.eventSink(SendLocationEvents.RequestPermissions) + myLocationState.eventSink(ShareLocationEvents.RequestPermissions) assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions) } } @Test fun `permission denied dialog dismiss`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -244,23 +244,23 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(SendLocationState.Dialog.PermissionDenied) - assertThat(myLocationState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) + assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - myLocationState.eventSink(SendLocationEvents.DismissDialog) + myLocationState.eventSink(ShareLocationEvents.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) - assertThat(dialogDismissedState.mode).isEqualTo(SendLocationState.Mode.PinLocation) + assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(dialogDismissedState.hasLocationPermission).isFalse() } } @@ -275,7 +275,7 @@ class SendLocationPresenterTest { sendLocationLambda = sendLocationResult }, ) - val sendLocationPresenter = createSendLocationPresenter(joinedRoom) + val shareLocationPresenter = createShareLocationPresenter(joinedRoom) fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.AllGranted, @@ -284,15 +284,15 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Send location initialState.eventSink( - SendLocationEvents.SendLocation( - cameraPosition = SendLocationEvents.SendLocation.CameraPosition( + ShareLocationEvents.ShareLocation( + cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -339,7 +339,7 @@ class SendLocationPresenterTest { sendLocationLambda = sendLocationResult }, ) - val sendLocationPresenter = createSendLocationPresenter(joinedRoom) + val shareLocationPresenter = createShareLocationPresenter(joinedRoom) fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -348,15 +348,15 @@ class SendLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Send location initialState.eventSink( - SendLocationEvents.SendLocation( - cameraPosition = SendLocationEvents.SendLocation.CameraPosition( + ShareLocationEvents.ShareLocation( + cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -403,7 +403,7 @@ class SendLocationPresenterTest { sendLocationLambda = sendLocationResult }, ) - val sendLocationPresenter = createSendLocationPresenter(joinedRoom) + val shareLocationPresenter = createShareLocationPresenter(joinedRoom) fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -418,15 +418,15 @@ class SendLocationPresenterTest { } moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() // Send location initialState.eventSink( - SendLocationEvents.SendLocation( - cameraPosition = SendLocationEvents.SendLocation.CameraPosition( + ShareLocationEvents.ShareLocation( + cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -451,7 +451,7 @@ class SendLocationPresenterTest { @Test fun `open settings activity`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.NoneGranted, @@ -466,28 +466,28 @@ class SendLocationPresenterTest { } moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { // Skip initial state val initialState = awaitItem() - initialState.eventSink(SendLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) val dialogShownState = awaitItem() // Open settings - dialogShownState.eventSink(SendLocationEvents.OpenAppSettings) + dialogShownState.eventSink(ShareLocationEvents.OpenAppSettings) val settingsOpenedState = awaitItem() - assertThat(settingsOpenedState.permissionDialog).isEqualTo(SendLocationState.Dialog.None) + assertThat(settingsOpenedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) assertThat(fakeLocationActions.openSettingsInvocationsCount).isEqualTo(1) } } @Test fun `application name is in state`() = runTest { - val sendLocationPresenter = createSendLocationPresenter() + val shareLocationPresenter = createShareLocationPresenter() moleculeFlow(RecompositionMode.Immediate) { - sendLocationPresenter.present() + shareLocationPresenter.present() }.test { val initialState = awaitItem() assertThat(initialState.appName).isEqualTo("app name") diff --git a/features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeSendLocationEntryPoint.kt b/features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeShareLocationEntryPoint.kt similarity index 83% rename from features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeSendLocationEntryPoint.kt rename to features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeShareLocationEntryPoint.kt index 2a1741e6c8..9fbbf2a7a2 100644 --- a/features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeSendLocationEntryPoint.kt +++ b/features/location/test/src/main/kotlin/io/element/android/features/location/test/FakeShareLocationEntryPoint.kt @@ -10,11 +10,11 @@ package io.element.android.features.location.test import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node -import io.element.android.features.location.api.SendLocationEntryPoint +import io.element.android.features.location.api.ShareLocationEntryPoint import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.tests.testutils.lambda.lambdaError -class FakeSendLocationEntryPoint : SendLocationEntryPoint { +class FakeShareLocationEntryPoint : ShareLocationEntryPoint { override fun createNode( parentNode: Node, buildContext: BuildContext, 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 8342184b12..b28574cdbf 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 @@ -30,7 +30,7 @@ import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint import io.element.android.features.location.api.Location import io.element.android.features.location.api.LocationService -import io.element.android.features.location.api.SendLocationEntryPoint +import io.element.android.features.location.api.ShareLocationEntryPoint import io.element.android.features.location.api.ShowLocationEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.impl.attachments.Attachment @@ -102,7 +102,7 @@ class MessagesFlowNode( @Assisted plugins: List, private val roomListService: RoomListService, private val sessionId: SessionId, - private val sendLocationEntryPoint: SendLocationEntryPoint, + private val shareLocationEntryPoint: ShareLocationEntryPoint, private val showLocationEntryPoint: ShowLocationEntryPoint, private val createPollEntryPoint: CreatePollEntryPoint, private val elementCallEntryPoint: ElementCallEntryPoint, @@ -374,7 +374,7 @@ class MessagesFlowNode( createNode(buildContext, listOf(inputs)) } is NavTarget.SendLocation -> { - sendLocationEntryPoint.createNode( + shareLocationEntryPoint.createNode( parentNode = this, buildContext = buildContext, timelineMode = navTarget.timelineMode, 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 90c31b911a..a1db09dfda 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 @@ -17,7 +17,7 @@ import io.element.android.features.call.test.FakeElementCallEntryPoint import io.element.android.features.forward.test.FakeForwardEntryPoint import io.element.android.features.knockrequests.test.FakeKnockRequestsListEntryPoint import io.element.android.features.location.test.FakeLocationService -import io.element.android.features.location.test.FakeSendLocationEntryPoint +import io.element.android.features.location.test.FakeShareLocationEntryPoint import io.element.android.features.location.test.FakeShowLocationEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.impl.pinned.banner.createPinnedEventsTimelineProvider @@ -62,7 +62,7 @@ class DefaultMessagesEntryPointTest { plugins = plugins, roomListService = FakeRoomListService(), sessionId = A_SESSION_ID, - sendLocationEntryPoint = FakeSendLocationEntryPoint(), + shareLocationEntryPoint = FakeShareLocationEntryPoint(), showLocationEntryPoint = FakeShowLocationEntryPoint(), createPollEntryPoint = FakeCreatePollEntryPoint(), elementCallEntryPoint = FakeElementCallEntryPoint(), From add737b64654a0c55b4ccba6a76f8b58a8e2fafc Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 17:24:20 +0100 Subject: [PATCH 004/103] Rename ShareLocationEvents -> ShareLocationEvent --- ...ocationEvents.kt => ShareLocationEvent.kt} | 18 +-- .../impl/share/ShareLocationPresenter.kt | 21 +-- .../location/impl/share/ShareLocationView.kt | 129 +++++++++++------- .../impl/share/ShareLocationPresenterTest.kt | 36 ++--- 4 files changed, 122 insertions(+), 82 deletions(-) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/{ShareLocationEvents.kt => ShareLocationEvent.kt} (56%) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt similarity index 56% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index 93b75d8e38..b5d45b8147 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvents.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -10,11 +10,11 @@ package io.element.android.features.location.impl.share import io.element.android.features.location.api.Location -sealed interface ShareLocationEvents { - data class ShareLocation( +sealed interface ShareLocationEvent { + data class ShareStaticLocation( val cameraPosition: CameraPosition, val location: Location?, - ) : ShareLocationEvents { + ) : ShareLocationEvent { data class CameraPosition( val lat: Double, val lon: Double, @@ -22,9 +22,11 @@ sealed interface ShareLocationEvents { ) } - data object SwitchToMyLocationMode : ShareLocationEvents - data object SwitchToPinLocationMode : ShareLocationEvents - data object DismissDialog : ShareLocationEvents - data object RequestPermissions : ShareLocationEvents - data object OpenAppSettings : ShareLocationEvents + data object SelectLiveLocationDuration: ShareLocationEvent + + data object SwitchToMyLocationMode : ShareLocationEvent + data object SwitchToPinLocationMode : ShareLocationEvent + data object DismissDialog : ShareLocationEvent + data object RequestPermissions : ShareLocationEvent + data object OpenAppSettings : ShareLocationEvent } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 5b2b7ebc25..7f9f9a9874 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -79,23 +79,24 @@ class ShareLocationPresenter( } } - fun handleEvent(event: ShareLocationEvents) { + fun handleEvent(event: ShareLocationEvent) { when (event) { - is ShareLocationEvents.ShareLocation -> scope.launch { + is ShareLocationEvent.ShareStaticLocation -> scope.launch { shareLocation(event, mode) } - ShareLocationEvents.SwitchToMyLocationMode -> when { + ShareLocationEvent.SwitchToMyLocationMode -> when { permissionsState.isAnyGranted -> mode = ShareLocationState.Mode.SenderLocation permissionsState.shouldShowRationale -> permissionDialog = ShareLocationState.Dialog.PermissionRationale else -> permissionDialog = ShareLocationState.Dialog.PermissionDenied } - ShareLocationEvents.SwitchToPinLocationMode -> mode = ShareLocationState.Mode.PinLocation - ShareLocationEvents.DismissDialog -> permissionDialog = ShareLocationState.Dialog.None - ShareLocationEvents.OpenAppSettings -> { + ShareLocationEvent.SwitchToPinLocationMode -> mode = ShareLocationState.Mode.PinLocation + ShareLocationEvent.DismissDialog -> permissionDialog = ShareLocationState.Dialog.None + ShareLocationEvent.OpenAppSettings -> { locationActions.openSettings() permissionDialog = ShareLocationState.Dialog.None } - ShareLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) + ShareLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) + ShareLocationEvent.SelectLiveLocationDuration -> Unit } } @@ -109,7 +110,7 @@ class ShareLocationPresenter( } private suspend fun shareLocation( - event: ShareLocationEvents.ShareLocation, + event: ShareLocationEvent.ShareStaticLocation, mode: ShareLocationState.Mode, ) { val replyMode = messageComposerContext.composerMode as? MessageComposerMode.Reply @@ -168,8 +169,8 @@ class ShareLocationPresenter( } } -private fun ShareLocationEvents.ShareLocation.toGeoUri(): String = location?.toGeoUri() ?: cameraPosition.toGeoUri() +private fun ShareLocationEvent.ShareStaticLocation.toGeoUri(): String = location?.toGeoUri() ?: cameraPosition.toGeoUri() -private fun ShareLocationEvents.ShareLocation.CameraPosition.toGeoUri(): String = "geo:$lat,$lon" +private fun ShareLocationEvent.ShareStaticLocation.CameraPosition.toGeoUri(): String = "geo:$lat,$lon" private fun generateBody(uri: String): String = "Location was shared at $uri" diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 1c9e85c82b..6e83406367 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -19,7 +19,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ListItem import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState @@ -31,24 +30,29 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource 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.location.api.Location import io.element.android.features.location.api.internal.centerBottomEdge import io.element.android.features.location.api.internal.rememberTileStyleUrl -import io.element.android.features.location.impl.R import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.IconSource +import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.maplibre.compose.CameraMode import io.element.android.libraries.maplibre.compose.CameraMoveStartedReason +import io.element.android.libraries.maplibre.compose.CameraPositionState import io.element.android.libraries.maplibre.compose.MapLibreMap import io.element.android.libraries.maplibre.compose.rememberCameraPositionState import io.element.android.libraries.ui.strings.CommonStrings @@ -62,19 +66,19 @@ fun ShareLocationView( modifier: Modifier = Modifier, ) { LaunchedEffect(Unit) { - state.eventSink(ShareLocationEvents.RequestPermissions) + state.eventSink(ShareLocationEvent.RequestPermissions) } when (state.permissionDialog) { ShareLocationState.Dialog.None -> Unit ShareLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( - onContinue = { state.eventSink(ShareLocationEvents.OpenAppSettings) }, - onDismiss = { state.eventSink(ShareLocationEvents.DismissDialog) }, + onContinue = { state.eventSink(ShareLocationEvent.OpenAppSettings) }, + onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, appName = state.appName, ) ShareLocationState.Dialog.PermissionRationale -> PermissionRationaleDialog( - onContinue = { state.eventSink(ShareLocationEvents.RequestPermissions) }, - onDismiss = { state.eventSink(ShareLocationEvents.DismissDialog) }, + onContinue = { state.eventSink(ShareLocationEvent.RequestPermissions) }, + onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, appName = state.appName, ) } @@ -99,7 +103,7 @@ fun ShareLocationView( LaunchedEffect(cameraPositionState.isMoving) { if (cameraPositionState.cameraMoveStartedReason == CameraMoveStartedReason.GESTURE) { - state.eventSink(ShareLocationEvents.SwitchToPinLocationMode) + state.eventSink(ShareLocationEvent.SwitchToPinLocationMode) } } @@ -108,48 +112,35 @@ fun ShareLocationView( BottomSheetScaffold( sheetContent = { - Spacer(modifier = Modifier.height(16.dp)) + Spacer(Modifier.height(20.dp)) ListItem( headlineContent = { Text( - stringResource( - when (state.mode) { - ShareLocationState.Mode.PinLocation -> CommonStrings.screen_share_this_location_action - ShareLocationState.Mode.SenderLocation -> CommonStrings.screen_share_my_location_action - } - ) + text = "Sharing options", + style = ElementTheme.typography.fontBodyLgMedium, ) - }, - modifier = Modifier.clickable( - // target is null when the map hasn't loaded (or api key is wrong) so we disable the button - enabled = cameraPositionState.position.target != null - ) { - state.eventSink( - ShareLocationEvents.ShareLocation( - cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( - lat = cameraPositionState.position.target!!.latitude, - lon = cameraPositionState.position.target!!.longitude, - zoom = cameraPositionState.position.zoom, - ), - location = cameraPositionState.location?.let { - Location( - lat = it.latitude, - lon = it.longitude, - accuracy = it.accuracy, - ) - } - ) - ) - navigateUp() - }, - leadingContent = { - Icon( - resourceId = R.drawable.pin_small, - contentDescription = null, - tint = Color.Unspecified, - ) - }, + } ) + StaticLocationItem(state.mode, cameraPositionState){ + val positionTarget = cameraPositionState.position.target ?: return@StaticLocationItem + state.eventSink( + ShareLocationEvent.ShareStaticLocation( + cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( + lat = positionTarget.latitude, + lon = positionTarget.longitude, + zoom = cameraPositionState.position.zoom, + ), + location = cameraPositionState.location?.let { + Location( + lat = it.latitude, + lon = it.longitude, + accuracy = it.accuracy, + ) + } + ) + ) + navigateUp() + } Spacer(modifier = Modifier.height(16.dp + navBarPadding)) }, modifier = modifier, @@ -191,7 +182,7 @@ fun ShareLocationView( ) LocationFloatingActionButton( isMapCenteredOnUser = state.mode == ShareLocationState.Mode.SenderLocation, - onClick = { state.eventSink(ShareLocationEvents.SwitchToMyLocationMode) }, + onClick = { state.eventSink(ShareLocationEvent.SwitchToMyLocationMode) }, modifier = Modifier .align(Alignment.BottomEnd) .padding(end = 18.dp, bottom = 72.dp + navBarPadding), @@ -200,6 +191,52 @@ fun ShareLocationView( } } +@Composable +private fun StaticLocationItem( + mode: ShareLocationState.Mode, + cameraPositionState: CameraPositionState, + onClick: ()->Unit, +) { + ListItem( + headlineContent = { + Text( + stringResource( + when (mode) { + ShareLocationState.Mode.PinLocation -> CommonStrings.screen_share_this_location_action + ShareLocationState.Mode.SenderLocation -> CommonStrings.screen_share_my_location_action + } + ) + ) + }, + modifier = Modifier.clickable( + // target is null when the map hasn't loaded (or api key is wrong) so we disable the button + enabled = cameraPositionState.position.target != null, + onClick = onClick + ), + leadingContent = ListItemContent.Icon( + iconSource = IconSource.Vector(CompoundIcons.LocationNavigatorCentred()) + ) + ) +} + +@Composable +private fun LiveLocationItem( + onClick: ()->Unit, +) { + ListItem( + headlineContent = { + Text("Share live location") + }, + modifier = Modifier.clickable( + onClick = onClick + ), + leadingContent = ListItemContent.Icon( + iconSource = IconSource.Vector(CompoundIcons.LocationPinSolid()), + tintColor = ElementTheme.colors.iconAccentPrimary, + ) + ) +} + @PreviewsDayNight @Composable internal fun ShareLocationViewPreview( diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index ead3fb2fe0..3d4a5b519e 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -83,7 +83,7 @@ class ShareLocationPresenterTest { assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToPinLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -110,7 +110,7 @@ class ShareLocationPresenterTest { assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToPinLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -137,7 +137,7 @@ class ShareLocationPresenterTest { assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -164,7 +164,7 @@ class ShareLocationPresenterTest { assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -189,14 +189,14 @@ class ShareLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - myLocationState.eventSink(ShareLocationEvents.DismissDialog) + myLocationState.eventSink(ShareLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -221,14 +221,14 @@ class ShareLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Continue the dialog sends permission request to the permissions presenter - myLocationState.eventSink(ShareLocationEvents.RequestPermissions) + myLocationState.eventSink(ShareLocationEvent.RequestPermissions) assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions) } } @@ -250,14 +250,14 @@ class ShareLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - myLocationState.eventSink(ShareLocationEvents.DismissDialog) + myLocationState.eventSink(ShareLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) @@ -291,8 +291,8 @@ class ShareLocationPresenterTest { // Send location initialState.eventSink( - ShareLocationEvents.ShareLocation( - cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( + ShareLocationEvent.ShareStaticLocation( + cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -355,8 +355,8 @@ class ShareLocationPresenterTest { // Send location initialState.eventSink( - ShareLocationEvents.ShareLocation( - cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( + ShareLocationEvent.ShareStaticLocation( + cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -425,8 +425,8 @@ class ShareLocationPresenterTest { // Send location initialState.eventSink( - ShareLocationEvents.ShareLocation( - cameraPosition = ShareLocationEvents.ShareLocation.CameraPosition( + ShareLocationEvent.ShareStaticLocation( + cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( lat = 0.0, lon = 1.0, zoom = 2.0, @@ -471,11 +471,11 @@ class ShareLocationPresenterTest { // Skip initial state val initialState = awaitItem() - initialState.eventSink(ShareLocationEvents.SwitchToMyLocationMode) + initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val dialogShownState = awaitItem() // Open settings - dialogShownState.eventSink(ShareLocationEvents.OpenAppSettings) + dialogShownState.eventSink(ShareLocationEvent.OpenAppSettings) val settingsOpenedState = awaitItem() assertThat(settingsOpenedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) From a129d1f9ca2258258c6ef5b967a7c97ff3c55262 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 17:24:38 +0100 Subject: [PATCH 005/103] Add share live location item --- features/location/impl/build.gradle.kts | 2 ++ .../location/impl/share/ShareLocationPresenter.kt | 8 ++++++++ .../features/location/impl/share/ShareLocationState.kt | 3 ++- .../location/impl/share/ShareLocationStateProvider.kt | 2 ++ .../features/location/impl/share/ShareLocationView.kt | 5 +++++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index bd41c7ecdf..3b805d87ca 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -39,10 +39,12 @@ dependencies { implementation(projects.services.analytics.api) implementation(libs.accompanist.permission) implementation(projects.libraries.uiStrings) + implementation(projects.libraries.featureflag.api) testCommonDependencies(libs, true) testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.testtags) testImplementation(projects.services.analytics.test) testImplementation(projects.features.messages.test) + testImplementation(projects.libraries.featureflag.test) } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 7f9f9a9874..f92d8af92d 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -10,6 +10,7 @@ package io.element.android.features.location.impl.share import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -29,6 +30,8 @@ import io.element.android.features.messages.api.MessageComposerContext import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.room.CreateTimelineParams import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType @@ -46,6 +49,7 @@ class ShareLocationPresenter( private val messageComposerContext: MessageComposerContext, private val locationActions: LocationActions, private val buildMeta: BuildMeta, + private val featureFlagService: FeatureFlagService, ) : Presenter { @AssistedFactory fun interface Factory { @@ -66,6 +70,9 @@ class ShareLocationPresenter( } ) } + val isLiveLocationSharingEnabled by remember { + featureFlagService.isFeatureEnabledFlow(FeatureFlags.LiveLocationSharing) + }.collectAsState(false) val appName by remember { derivedStateOf { buildMeta.applicationName } } var permissionDialog: ShareLocationState.Dialog by remember { mutableStateOf(ShareLocationState.Dialog.None) @@ -104,6 +111,7 @@ class ShareLocationPresenter( permissionDialog = permissionDialog, mode = mode, hasLocationPermission = permissionsState.isAnyGranted, + canShareLiveLocation = isLiveLocationSharingEnabled, appName = appName, eventSink = ::handleEvent, ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 14975f1646..69971b342e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -13,7 +13,8 @@ data class ShareLocationState( val mode: Mode, val hasLocationPermission: Boolean, val appName: String, - val eventSink: (ShareLocationEvents) -> Unit, + val canShareLiveLocation: Boolean, + val eventSink: (ShareLocationEvent) -> Unit, ) { sealed interface Mode { data object SenderLocation : Mode diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index df49881975..b22e8e6606 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -47,11 +47,13 @@ private fun aShareLocationState( permissionDialog: ShareLocationState.Dialog, mode: ShareLocationState.Mode, hasLocationPermission: Boolean, + canShareLiveLocation: Boolean = false, ): ShareLocationState { return ShareLocationState( permissionDialog = permissionDialog, mode = mode, hasLocationPermission = hasLocationPermission, + canShareLiveLocation = canShareLiveLocation, appName = APP_NAME, eventSink = {} ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 6e83406367..27ade66c88 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -141,6 +141,11 @@ fun ShareLocationView( ) navigateUp() } + if(state.canShareLiveLocation){ + LiveLocationItem { + state.eventSink(ShareLocationEvent.SelectLiveLocationDuration) + } + } Spacer(modifier = Modifier.height(16.dp + navBarPadding)) }, modifier = modifier, From 7472f889cf848c5e5f26d96e65e076be8037a167 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 18 Feb 2026 19:13:47 +0100 Subject: [PATCH 006/103] Allow picking duration for the live location share --- .../impl/share/LiveLocationDuration.kt | 21 +++++++++ .../location/impl/share/ShareLocationEvent.kt | 4 +- .../impl/share/ShareLocationPresenter.kt | 24 ++++++---- .../location/impl/share/ShareLocationState.kt | 3 +- .../impl/share/ShareLocationStateProvider.kt | 8 +++- .../location/impl/share/ShareLocationView.kt | 46 ++++++++++++++++++- .../impl/share/ShareLocationPresenterTest.kt | 28 +++++------ .../components/dialogs/ListDialog.kt | 7 ++- 8 files changed, 113 insertions(+), 28 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt new file mode 100644 index 0000000000..8763263d57 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Element Creations 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.location.impl.share + +import kotlin.time.Duration +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes + +enum class LiveLocationDuration( + val duration: Duration, + val label: String, +) { + FifteenMinutes(15.minutes, "15 minutes"), + OneHour(1.hours, "1 hour"), + EightHours(8.hours, "8 hours"); +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index b5d45b8147..9ac15742d9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -9,6 +9,7 @@ package io.element.android.features.location.impl.share import io.element.android.features.location.api.Location +import kotlin.time.Duration sealed interface ShareLocationEvent { data class ShareStaticLocation( @@ -22,7 +23,8 @@ sealed interface ShareLocationEvent { ) } - data object SelectLiveLocationDuration: ShareLocationEvent + data object SelectLiveLocationDuration : ShareLocationEvent + data class StartLiveLocationShare(val duration: Duration) : ShareLocationEvent data object SwitchToMyLocationMode : ShareLocationEvent data object SwitchToPinLocationMode : ShareLocationEvent diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index f92d8af92d..d53b132314 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -74,7 +74,7 @@ class ShareLocationPresenter( featureFlagService.isFeatureEnabledFlow(FeatureFlags.LiveLocationSharing) }.collectAsState(false) val appName by remember { derivedStateOf { buildMeta.applicationName } } - var permissionDialog: ShareLocationState.Dialog by remember { + var dialogState: ShareLocationState.Dialog by remember { mutableStateOf(ShareLocationState.Dialog.None) } val scope = rememberCoroutineScope() @@ -82,7 +82,7 @@ class ShareLocationPresenter( LaunchedEffect(permissionsState.permissions) { if (permissionsState.isAnyGranted) { mode = ShareLocationState.Mode.SenderLocation - permissionDialog = ShareLocationState.Dialog.None + dialogState = ShareLocationState.Dialog.None } } @@ -93,22 +93,30 @@ class ShareLocationPresenter( } ShareLocationEvent.SwitchToMyLocationMode -> when { permissionsState.isAnyGranted -> mode = ShareLocationState.Mode.SenderLocation - permissionsState.shouldShowRationale -> permissionDialog = ShareLocationState.Dialog.PermissionRationale - else -> permissionDialog = ShareLocationState.Dialog.PermissionDenied + permissionsState.shouldShowRationale -> dialogState = ShareLocationState.Dialog.PermissionRationale + else -> dialogState = ShareLocationState.Dialog.PermissionDenied } ShareLocationEvent.SwitchToPinLocationMode -> mode = ShareLocationState.Mode.PinLocation - ShareLocationEvent.DismissDialog -> permissionDialog = ShareLocationState.Dialog.None + ShareLocationEvent.DismissDialog -> dialogState = ShareLocationState.Dialog.None ShareLocationEvent.OpenAppSettings -> { locationActions.openSettings() - permissionDialog = ShareLocationState.Dialog.None + dialogState = ShareLocationState.Dialog.None } ShareLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) - ShareLocationEvent.SelectLiveLocationDuration -> Unit + ShareLocationEvent.SelectLiveLocationDuration -> dialogState = when { + permissionsState.isAnyGranted -> ShareLocationState.Dialog.LiveLocationDuration + permissionsState.shouldShowRationale -> ShareLocationState.Dialog.PermissionRationale + else -> ShareLocationState.Dialog.PermissionDenied + } + is ShareLocationEvent.StartLiveLocationShare -> scope.launch { + dialogState = ShareLocationState.Dialog.None + //room.startLiveLocationShare(event.duration.inWholeMilliseconds) + } } } return ShareLocationState( - permissionDialog = permissionDialog, + dialogState = dialogState, mode = mode, hasLocationPermission = permissionsState.isAnyGranted, canShareLiveLocation = isLiveLocationSharingEnabled, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 69971b342e..952e728097 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -9,7 +9,7 @@ package io.element.android.features.location.impl.share data class ShareLocationState( - val permissionDialog: Dialog, + val dialogState: Dialog, val mode: Mode, val hasLocationPermission: Boolean, val appName: String, @@ -25,5 +25,6 @@ data class ShareLocationState( data object None : Dialog data object PermissionRationale : Dialog data object PermissionDenied : Dialog + data object LiveLocationDuration : Dialog } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index b22e8e6606..8832184f18 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -40,6 +40,12 @@ class ShareLocationStateProvider : PreviewParameterProvider mode = ShareLocationState.Mode.SenderLocation, hasLocationPermission = true, ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.LiveLocationDuration, + mode = ShareLocationState.Mode.SenderLocation, + hasLocationPermission = true, + canShareLiveLocation = true, + ), ) } @@ -50,7 +56,7 @@ private fun aShareLocationState( canShareLiveLocation: Boolean = false, ): ShareLocationState { return ShareLocationState( - permissionDialog = permissionDialog, + dialogState = permissionDialog, mode = mode, hasLocationPermission = hasLocationPermission, canShareLiveLocation = canShareLiveLocation, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 27ade66c88..62cb38fd9b 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -9,6 +9,7 @@ package io.element.android.features.location.impl.share import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets @@ -22,8 +23,13 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -40,7 +46,9 @@ import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent +import io.element.android.libraries.designsystem.components.list.RadioButtonListItem import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold @@ -57,6 +65,7 @@ import io.element.android.libraries.maplibre.compose.MapLibreMap import io.element.android.libraries.maplibre.compose.rememberCameraPositionState import io.element.android.libraries.ui.strings.CommonStrings import org.maplibre.android.camera.CameraPosition +import kotlin.time.Duration @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -69,7 +78,7 @@ fun ShareLocationView( state.eventSink(ShareLocationEvent.RequestPermissions) } - when (state.permissionDialog) { + when (state.dialogState) { ShareLocationState.Dialog.None -> Unit ShareLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( onContinue = { state.eventSink(ShareLocationEvent.OpenAppSettings) }, @@ -81,6 +90,13 @@ fun ShareLocationView( onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, appName = state.appName, ) + ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog( + onSelectDuration = { duration -> + state.eventSink(ShareLocationEvent.StartLiveLocationShare(duration)) + navigateUp() + }, + onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, + ) } val cameraPositionState = rememberCameraPositionState { @@ -226,7 +242,7 @@ private fun StaticLocationItem( @Composable private fun LiveLocationItem( - onClick: ()->Unit, + onClick: () -> Unit, ) { ListItem( headlineContent = { @@ -242,6 +258,32 @@ private fun LiveLocationItem( ) } +@Composable +private fun LiveLocationDurationDialog( + onSelectDuration: (Duration) -> Unit, + onDismiss: () -> Unit, +) { + var selectedIndex by remember { mutableIntStateOf(0) } + ListDialog( + title = "Choose how long to share your live location.", + submitText = stringResource(CommonStrings.action_continue), + onSubmit = { onSelectDuration(LiveLocationDuration.entries[selectedIndex].duration) }, + onDismissRequest = onDismiss, + applyPaddingToContents = false, + verticalArrangement = Arrangement.Top + ) { + itemsIndexed(LiveLocationDuration.entries) { index, duration -> + RadioButtonListItem( + headline = duration.label, + selected = index == selectedIndex, + onSelect = { selectedIndex = index }, + compactLayout = true, + modifier = Modifier.padding(start = 8.dp) + ) + } + } +} + @PreviewsDayNight @Composable internal fun ShareLocationViewPreview( diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 3d4a5b519e..8d34fb99d6 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -78,14 +78,14 @@ class ShareLocationPresenterTest { shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isTrue() } @@ -105,14 +105,14 @@ class ShareLocationPresenterTest { shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) assertThat(initialState.hasLocationPermission).isTrue() // Swipe the map to switch mode initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isTrue() } @@ -132,14 +132,14 @@ class ShareLocationPresenterTest { shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionDenied) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() } @@ -159,14 +159,14 @@ class ShareLocationPresenterTest { shareLocationPresenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(initialState.hasLocationPermission).isFalse() // Click on the button to switch mode initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() } @@ -191,14 +191,14 @@ class ShareLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog myLocationState.eventSink(ShareLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(dialogDismissedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(dialogDismissedState.hasLocationPermission).isFalse() } @@ -223,7 +223,7 @@ class ShareLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionRationale) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() @@ -252,14 +252,14 @@ class ShareLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) val myLocationState = awaitItem() - assertThat(myLocationState.permissionDialog).isEqualTo(ShareLocationState.Dialog.PermissionDenied) + assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionDenied) assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(myLocationState.hasLocationPermission).isFalse() // Dismiss the dialog myLocationState.eventSink(ShareLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(dialogDismissedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) assertThat(dialogDismissedState.hasLocationPermission).isFalse() } @@ -478,7 +478,7 @@ class ShareLocationPresenterTest { dialogShownState.eventSink(ShareLocationEvent.OpenAppSettings) val settingsOpenedState = awaitItem() - assertThat(settingsOpenedState.permissionDialog).isEqualTo(ShareLocationState.Dialog.None) + assertThat(settingsOpenedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) assertThat(fakeLocationActions.openSettingsInvocationsCount).isEqualTo(1) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt index ce1afae93d..ffaab12eba 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.components.dialogs import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope @@ -42,6 +43,7 @@ fun ListDialog( enabled: Boolean = true, applyPaddingToContents: Boolean = true, destructiveSubmit: Boolean = false, + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(16.dp), listItems: LazyListScope.() -> Unit, ) { val decoratedSubtitle: @Composable (() -> Unit)? = subtitle?.let { @@ -67,6 +69,7 @@ fun ListDialog( listItems = listItems, applyPaddingToContents = applyPaddingToContents, destructiveSubmit = destructiveSubmit, + verticalArrangement = verticalArrangement, ) } } @@ -82,6 +85,7 @@ private fun ListDialogContent( enabled: Boolean, applyPaddingToContents: Boolean, destructiveSubmit: Boolean, + verticalArrangement: Arrangement.Vertical, subtitle: @Composable (() -> Unit)? = null, ) { SimpleAlertDialogContent( @@ -99,7 +103,7 @@ private fun ListDialogContent( val horizontalPadding = if (applyPaddingToContents) 0.dp else 8.dp LazyColumn( modifier = Modifier.padding(horizontal = horizontalPadding), - verticalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = verticalArrangement, ) { listItems() } } } @@ -126,6 +130,7 @@ internal fun ListDialogContentPreview() { enabled = true, destructiveSubmit = false, applyPaddingToContents = true, + verticalArrangement = Arrangement.spacedBy(16.dp), ) } } From b49fd7b4677c7c796884e72a571f7bea03783200 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 26 Feb 2026 15:41:52 +0100 Subject: [PATCH 007/103] Add maplibre-compose to gradle catalog --- app/build.gradle.kts | 1 + gradle/libs.versions.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 969f401385..64bd398446 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -334,6 +334,7 @@ licensee { allow("BSD-2-Clause") allow("BSD-3-Clause") allow("EPL-1.0") + allowUrl("https://opensource.org/license/bsd-3-clause") allowUrl("https://opensource.org/licenses/MIT") allowUrl("https://developer.android.com/studio/terms.html") allowUrl("https://www.zetetic.net/sqlcipher/license/") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e70308cccd..e5fe99bf17 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -209,6 +209,7 @@ telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = " statemachine = "com.freeletics.flowredux:compose:1.2.2" maplibre = "org.maplibre.gl:android-sdk:13.0.0" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" +maplibre_compose = "org.maplibre.compose:maplibre-compose:0.12.1" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" zxing_cpp = "io.github.zxing-cpp:android:3.0.2" From 29f9640053940ede3426be35a4ab8cee9bb0430d Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 26 Feb 2026 15:54:41 +0100 Subject: [PATCH 008/103] Location accuracy should be nullable --- .../android/features/location/api/Location.kt | 11 +++++++---- .../android/features/location/api/LocationKtTest.kt | 13 ++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/Location.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/Location.kt index 7593867207..eac624fe8b 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/Location.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/Location.kt @@ -19,7 +19,7 @@ private const val GEO_URI_REGEX = """geo:(?-?\d+(?:\.\d+)?),(? Date: Thu, 26 Feb 2026 18:28:46 +0100 Subject: [PATCH 009/103] First iteration using maplibre-compose --- features/location/impl/build.gradle.kts | 2 +- .../location/impl/common/MapDefaults.kt | 31 ++- .../common/ui/LocationFloatingActionButton.kt | 8 +- .../impl/common/ui/MapBottomSheetScaffold.kt | 130 +++++++++ .../location/impl/common/ui/UserLocation.kt | 52 ++++ .../location/impl/share/ShareLocationEvent.kt | 18 +- .../impl/share/ShareLocationPresenter.kt | 94 ++----- .../location/impl/share/ShareLocationState.kt | 7 +- .../impl/share/ShareLocationStateProvider.kt | 16 +- .../location/impl/share/ShareLocationView.kt | 253 +++++++++--------- .../location/impl/show/ShowLocationView.kt | 146 +++++----- 11 files changed, 456 insertions(+), 301 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index 3b805d87ca..558cd86b25 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -27,7 +27,7 @@ setupDependencyInjection() dependencies { api(projects.features.location.api) implementation(projects.features.messages.api) - implementation(projects.libraries.maplibreCompose) + implementation(libs.maplibre.compose) implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) implementation(projects.libraries.di) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt index d01f3e7dd2..6c01c75508 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt @@ -9,21 +9,30 @@ package io.element.android.features.location.impl.common import android.Manifest -import android.view.Gravity -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.ui.graphics.Color -import io.element.android.compound.theme.ElementTheme -import io.element.android.libraries.maplibre.compose.MapLocationSettings -import io.element.android.libraries.maplibre.compose.MapSymbolManagerSettings -import io.element.android.libraries.maplibre.compose.MapUiSettings -import org.maplibre.android.camera.CameraPosition -import org.maplibre.android.geometry.LatLng +import androidx.compose.ui.Alignment +import org.maplibre.compose.map.GestureOptions +import org.maplibre.compose.map.MapOptions +import org.maplibre.compose.map.OrnamentOptions +import org.maplibre.compose.map.RenderOptions /** * Common configuration values for the map. */ object MapDefaults { + val options = MapOptions( + renderOptions = RenderOptions.Standard, + gestureOptions = GestureOptions.Standard, + ornamentOptions = OrnamentOptions( + isLogoEnabled = true, + logoAlignment = Alignment.BottomStart, + isAttributionEnabled = true, + attributionAlignment = Alignment.BottomEnd, + isCompassEnabled = false, + isScaleBarEnabled = false, + ) + ) + + /* val uiSettings: MapUiSettings @Composable @ReadOnlyComposable @@ -60,6 +69,8 @@ object MapDefaults { .zoom(2.7) .build() + */ + const val DEFAULT_ZOOM = 15.0 val permissions = listOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt index 773544375f..99a4c7470f 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt @@ -9,6 +9,8 @@ package io.element.android.features.location.impl.common.ui import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.FloatingActionButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -30,13 +32,11 @@ internal fun LocationFloatingActionButton( modifier: Modifier = Modifier, ) { FloatingActionButton( - shape = FloatingActionButtonDefaults.smallShape, + shape = CircleShape, containerColor = ElementTheme.colors.bgCanvasDefault, contentColor = ElementTheme.colors.iconPrimary, onClick = onClick, - modifier = modifier - // Note: design is 40dp, but min is 48 for accessibility. - .size(48.dp), + modifier = modifier.size(48.dp), ) { val iconImage = if (isMapCenteredOnUser) { CompoundIcons.LocationNavigatorCentred() diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt new file mode 100644 index 0000000000..0a1b0cff9a --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Element Creations 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.location.impl.common.ui + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.material3.BottomSheetDefaults +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetValue +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.rememberBottomSheetScaffoldState +import androidx.compose.material3.rememberStandardBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.max +import io.element.android.features.location.api.internal.rememberTileStyleUrl +import io.element.android.features.location.impl.common.MapDefaults +import io.element.android.libraries.core.data.tryOrNull +import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold +import kotlin.math.roundToInt +import org.maplibre.compose.camera.CameraState +import org.maplibre.compose.camera.rememberCameraState +import org.maplibre.compose.map.MapOptions +import org.maplibre.compose.map.MaplibreMap +import org.maplibre.compose.style.BaseStyle +import org.maplibre.compose.util.MaplibreComposable + +/** + * A reusable scaffold component for map views with a bottom sheet. + * + * Handles the layout complexity of: + * - Calculating the visible sheet height dynamically + * - Updating camera position padding based on sheet height + * - Rendering the MaplibreMap with proper ornament positioning + * + * @param cameraState The camera state for the map + * @param topBar The top app bar content + * @param sheetContent The content to display in the bottom sheet + * @param modifier Modifier for the root layout + * @param scaffoldState State for the bottom sheet scaffold + * @param sheetPeekHeight The height of the sheet when collapsed + * @param sheetDragHandle Optional drag handle for the sheet + * @param sheetSwipeEnabled Whether the sheet can be swiped + * @param snackbarHost The snackbar host content + * @param mapContent The content inside the MaplibreMap (layers, location pucks, etc.) + * @param overlayContent Content to overlay on top of the map (FAB, pin icons, etc.) + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MapBottomSheetScaffold( + modifier: Modifier = Modifier, + scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded) + ), + cameraState: CameraState = rememberCameraState(), + mapOptions: MapOptions = MapDefaults.options, + sheetPeekHeight: Dp = BottomSheetDefaults.SheetPeekHeight, + sheetDragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() }, + sheetSwipeEnabled: Boolean = true, + topBar: (@Composable () -> Unit)? = null, + snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }, + sheetContent: @Composable ColumnScope.() -> Unit = {}, + mapContent: @Composable @MaplibreComposable () -> Unit = {}, + overlayContent: @Composable BoxScope.(sheetPadding: PaddingValues) -> Unit = {}, +) { + val density = LocalDensity.current + + BoxWithConstraints(modifier = modifier.safeDrawingPadding()) { + val layoutHeightPx by rememberUpdatedState(constraints.maxHeight) + val sheetPadding by remember { + derivedStateOf { + val sheetOffset = tryOrNull { scaffoldState.bottomSheetState.requireOffset() } ?: 0f + val sheetVisibleHeightPx = layoutHeightPx - sheetOffset + val bottomPadding = with(density) { max(sheetVisibleHeightPx.roundToInt().toDp(), 0.dp) } + PaddingValues(bottom = bottomPadding) + } + } + // Update camera position when sheet padding changes + LaunchedEffect(sheetPadding) { + cameraState.position = cameraState.position.copy(padding = sheetPadding) + } + + BottomSheetScaffold( + sheetPeekHeight = sheetPeekHeight, + sheetContent = { + sheetContent() + Spacer(modifier = Modifier.navigationBarsPadding()) + }, + scaffoldState = scaffoldState, + sheetDragHandle = sheetDragHandle, + sheetSwipeEnabled = sheetSwipeEnabled, + snackbarHost = snackbarHost, + topBar = topBar, + ) { + val ornamentOptions = mapOptions.ornamentOptions.copy(padding = sheetPadding) + Box { + MaplibreMap( + options = mapOptions.copy(ornamentOptions = ornamentOptions), + baseStyle = BaseStyle.Uri(rememberTileStyleUrl()), + modifier = Modifier.fillMaxSize(), + cameraState = cameraState, + content = mapContent, + ) + overlayContent(sheetPadding) + } + } + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt new file mode 100644 index 0000000000..9a5b6121b0 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import org.maplibre.compose.camera.CameraState +import org.maplibre.compose.location.LocationPuck +import org.maplibre.compose.location.LocationPuckColors +import org.maplibre.compose.location.LocationPuckSizes +import org.maplibre.compose.location.LocationTrackingEffect +import org.maplibre.compose.location.UserLocationState + +@Composable +fun UserLocation( + cameraState: CameraState, + locationState: UserLocationState, + trackUserLocation: Boolean, +) { + LocationTrackingEffect( + locationState = locationState, + enabled = trackUserLocation, + ) { + cameraState.updateFromLocation() + } + val location = locationState.location + if (location != null) { + LocationPuck( + idPrefix = "user-location", + locationState = locationState, + cameraState = cameraState, + accuracyThreshold = Float.POSITIVE_INFINITY, + showBearingAccuracy = false, + showBearing = false, + sizes = LocationPuckSizes( + dotRadius = 8.dp, + dotStrokeWidth = 2.dp, + ), + colors = LocationPuckColors( + dotFillColorCurrentLocation = ElementTheme.colors.iconAccentPrimary, + dotFillColorOldLocation = ElementTheme.colors.iconAccentTertiary, + dotStrokeColor = ElementTheme.colors.bgCanvasDefault, + ) + ) + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index 9ac15742d9..eb641df9fb 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -13,21 +13,15 @@ import kotlin.time.Duration sealed interface ShareLocationEvent { data class ShareStaticLocation( - val cameraPosition: CameraPosition, - val location: Location?, - ) : ShareLocationEvent { - data class CameraPosition( - val lat: Double, - val lon: Double, - val zoom: Double, - ) - } + val location: Location, + val isPinned: Boolean, + ) : ShareLocationEvent - data object SelectLiveLocationDuration : ShareLocationEvent + data object ShowLiveLocationDurationPicker : ShareLocationEvent data class StartLiveLocationShare(val duration: Duration) : ShareLocationEvent - data object SwitchToMyLocationMode : ShareLocationEvent - data object SwitchToPinLocationMode : ShareLocationEvent + data object StartTrackingUserPosition : ShareLocationEvent + data object StopTrackingUserPosition : ShareLocationEvent data object DismissDialog : ShareLocationEvent data object RequestPermissions : ShareLocationEvent data object OpenAppSettings : ShareLocationEvent diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index d53b132314..bd82b823f0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -61,15 +61,7 @@ class ShareLocationPresenter( @Composable override fun present(): ShareLocationState { val permissionsState: PermissionsState = permissionsPresenter.present() - var mode: ShareLocationState.Mode by remember { - mutableStateOf( - if (permissionsState.isAnyGranted) { - ShareLocationState.Mode.SenderLocation - } else { - ShareLocationState.Mode.PinLocation - } - ) - } + var trackUserPosition: Boolean by remember { mutableStateOf(permissionsState.isAnyGranted) } val isLiveLocationSharingEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.LiveLocationSharing) }.collectAsState(false) @@ -81,7 +73,7 @@ class ShareLocationPresenter( LaunchedEffect(permissionsState.permissions) { if (permissionsState.isAnyGranted) { - mode = ShareLocationState.Mode.SenderLocation + trackUserPosition = true dialogState = ShareLocationState.Dialog.None } } @@ -89,21 +81,21 @@ class ShareLocationPresenter( fun handleEvent(event: ShareLocationEvent) { when (event) { is ShareLocationEvent.ShareStaticLocation -> scope.launch { - shareLocation(event, mode) + shareStaticLocation(event) } - ShareLocationEvent.SwitchToMyLocationMode -> when { - permissionsState.isAnyGranted -> mode = ShareLocationState.Mode.SenderLocation + ShareLocationEvent.StartTrackingUserPosition -> when { + permissionsState.isAnyGranted -> trackUserPosition = true permissionsState.shouldShowRationale -> dialogState = ShareLocationState.Dialog.PermissionRationale else -> dialogState = ShareLocationState.Dialog.PermissionDenied } - ShareLocationEvent.SwitchToPinLocationMode -> mode = ShareLocationState.Mode.PinLocation + ShareLocationEvent.StopTrackingUserPosition -> trackUserPosition = false ShareLocationEvent.DismissDialog -> dialogState = ShareLocationState.Dialog.None ShareLocationEvent.OpenAppSettings -> { locationActions.openSettings() dialogState = ShareLocationState.Dialog.None } ShareLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) - ShareLocationEvent.SelectLiveLocationDuration -> dialogState = when { + ShareLocationEvent.ShowLiveLocationDurationPicker -> dialogState = when { permissionsState.isAnyGranted -> ShareLocationState.Dialog.LiveLocationDuration permissionsState.shouldShowRationale -> ShareLocationState.Dialog.PermissionRationale else -> ShareLocationState.Dialog.PermissionDenied @@ -117,7 +109,7 @@ class ShareLocationPresenter( return ShareLocationState( dialogState = dialogState, - mode = mode, + trackUserLocation = trackUserPosition, hasLocationPermission = permissionsState.isAnyGranted, canShareLiveLocation = isLiveLocationSharingEnabled, appName = appName, @@ -125,56 +117,28 @@ class ShareLocationPresenter( ) } - private suspend fun shareLocation( - event: ShareLocationEvent.ShareStaticLocation, - mode: ShareLocationState.Mode, - ) { + private suspend fun shareStaticLocation(event: ShareLocationEvent.ShareStaticLocation) { val replyMode = messageComposerContext.composerMode as? MessageComposerMode.Reply val inReplyToEventId = replyMode?.eventId - when (mode) { - ShareLocationState.Mode.PinLocation -> { - val geoUri = event.cameraPosition.toGeoUri() - getTimeline().flatMap { - it.sendLocation( - body = generateBody(geoUri), - geoUri = geoUri, - description = null, - zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(), - assetType = AssetType.PIN, - inReplyToEventId = inReplyToEventId, - ) - } - analyticsService.capture( - Composer( - inThread = messageComposerContext.composerMode.inThread, - isEditing = messageComposerContext.composerMode.isEditing, - isReply = messageComposerContext.composerMode.isReply, - messageType = Composer.MessageType.LocationPin, - ) - ) - } - ShareLocationState.Mode.SenderLocation -> { - val geoUri = event.toGeoUri() - getTimeline().flatMap { - it.sendLocation( - body = generateBody(geoUri), - geoUri = geoUri, - description = null, - zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(), - assetType = AssetType.SENDER, - inReplyToEventId = inReplyToEventId, - ) - } - analyticsService.capture( - Composer( - inThread = messageComposerContext.composerMode.inThread, - isEditing = messageComposerContext.composerMode.isEditing, - isReply = messageComposerContext.composerMode.isReply, - messageType = Composer.MessageType.LocationUser, - ) - ) - } + val geoUri = event.location.toGeoUri() + getTimeline().flatMap { + it.sendLocation( + body = generateBody(geoUri), + geoUri = geoUri, + description = null, + zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(), + assetType = if (event.isPinned) AssetType.PIN else AssetType.SENDER, + inReplyToEventId = inReplyToEventId, + ) } + analyticsService.capture( + Composer( + inThread = messageComposerContext.composerMode.inThread, + isEditing = messageComposerContext.composerMode.isEditing, + isReply = messageComposerContext.composerMode.isReply, + messageType = if (event.isPinned) Composer.MessageType.LocationPin else Composer.MessageType.LocationUser + ) + ) } private suspend fun getTimeline(): Result { @@ -185,8 +149,4 @@ class ShareLocationPresenter( } } -private fun ShareLocationEvent.ShareStaticLocation.toGeoUri(): String = location?.toGeoUri() ?: cameraPosition.toGeoUri() - -private fun ShareLocationEvent.ShareStaticLocation.CameraPosition.toGeoUri(): String = "geo:$lat,$lon" - private fun generateBody(uri: String): String = "Location was shared at $uri" diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 952e728097..947d286c5e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -10,17 +10,12 @@ package io.element.android.features.location.impl.share data class ShareLocationState( val dialogState: Dialog, - val mode: Mode, + val trackUserLocation: Boolean, val hasLocationPermission: Boolean, val appName: String, val canShareLiveLocation: Boolean, val eventSink: (ShareLocationEvent) -> Unit, ) { - sealed interface Mode { - data object SenderLocation : Mode - data object PinLocation : Mode - } - sealed interface Dialog { data object None : Dialog data object PermissionRationale : Dialog diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index 8832184f18..45a81af1df 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -17,32 +17,32 @@ class ShareLocationStateProvider : PreviewParameterProvider get() = sequenceOf( aShareLocationState( permissionDialog = ShareLocationState.Dialog.None, - mode = ShareLocationState.Mode.PinLocation, + trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.PermissionDenied, - mode = ShareLocationState.Mode.PinLocation, + trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.PermissionRationale, - mode = ShareLocationState.Mode.PinLocation, + trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.None, - mode = ShareLocationState.Mode.PinLocation, + trackUserPosition = false, hasLocationPermission = true, ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.None, - mode = ShareLocationState.Mode.SenderLocation, + trackUserPosition = true, hasLocationPermission = true, ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.LiveLocationDuration, - mode = ShareLocationState.Mode.SenderLocation, + trackUserPosition = true, hasLocationPermission = true, canShareLiveLocation = true, ), @@ -51,13 +51,13 @@ class ShareLocationStateProvider : PreviewParameterProvider private fun aShareLocationState( permissionDialog: ShareLocationState.Dialog, - mode: ShareLocationState.Mode, + trackUserPosition: Boolean, hasLocationPermission: Boolean, canShareLiveLocation: Boolean = false, ): ShareLocationState { return ShareLocationState( dialogState = permissionDialog, - mode = mode, + trackUserLocation = trackUserPosition, hasLocationPermission = hasLocationPermission, canShareLiveLocation = canShareLiveLocation, appName = APP_NAME, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 62cb38fd9b..84829d4bf9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -12,18 +12,14 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -40,32 +36,36 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.location.api.Location import io.element.android.features.location.api.internal.centerBottomEdge -import io.element.android.features.location.api.internal.rememberTileStyleUrl import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton +import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold +import io.element.android.features.location.impl.common.ui.UserLocation import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.RadioButtonListItem import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.utils.CommonDrawables -import io.element.android.libraries.maplibre.compose.CameraMode -import io.element.android.libraries.maplibre.compose.CameraMoveStartedReason -import io.element.android.libraries.maplibre.compose.CameraPositionState -import io.element.android.libraries.maplibre.compose.MapLibreMap -import io.element.android.libraries.maplibre.compose.rememberCameraPositionState import io.element.android.libraries.ui.strings.CommonStrings -import org.maplibre.android.camera.CameraPosition +import org.maplibre.compose.camera.CameraMoveReason +import org.maplibre.compose.camera.CameraPosition +import org.maplibre.compose.camera.CameraState +import org.maplibre.compose.camera.rememberCameraState +import org.maplibre.compose.location.DesiredAccuracy +import org.maplibre.compose.location.UserLocationState +import org.maplibre.compose.location.rememberDefaultLocationProvider +import org.maplibre.compose.location.rememberNullLocationProvider +import org.maplibre.compose.location.rememberUserLocationState import kotlin.time.Duration +import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -99,76 +99,32 @@ fun ShareLocationView( ) } - val cameraPositionState = rememberCameraPositionState { - position = MapDefaults.centerCameraPosition + val scaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded) + ) + val cameraState = rememberCameraState(firstPosition = CameraPosition(zoom = MapDefaults.DEFAULT_ZOOM)) + val locationProvider = if (state.hasLocationPermission) { + rememberDefaultLocationProvider( + updateInterval = 1.minutes, + desiredAccuracy = DesiredAccuracy.Balanced, + minDistanceMeters = 50.0, + ) + } else { + rememberNullLocationProvider() } + val userLocationState = rememberUserLocationState(locationProvider) - LaunchedEffect(state.mode) { - when (state.mode) { - ShareLocationState.Mode.PinLocation -> { - cameraPositionState.cameraMode = CameraMode.NONE - } - ShareLocationState.Mode.SenderLocation -> { - cameraPositionState.position = CameraPosition.Builder() - .zoom(MapDefaults.DEFAULT_ZOOM) - .build() - cameraPositionState.cameraMode = CameraMode.TRACKING - } + LaunchedEffect(cameraState.isCameraMoving) { + if (cameraState.moveReason == CameraMoveReason.GESTURE) { + state.eventSink(ShareLocationEvent.StopTrackingUserPosition) } } - LaunchedEffect(cameraPositionState.isMoving) { - if (cameraPositionState.cameraMoveStartedReason == CameraMoveStartedReason.GESTURE) { - state.eventSink(ShareLocationEvent.SwitchToPinLocationMode) - } - } - - // BottomSheetScaffold doesn't manage the system insets for sheetContent and the FAB, so we need to do it manually. - val navBarPadding = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() - - BottomSheetScaffold( - sheetContent = { - Spacer(Modifier.height(20.dp)) - ListItem( - headlineContent = { - Text( - text = "Sharing options", - style = ElementTheme.typography.fontBodyLgMedium, - ) - } - ) - StaticLocationItem(state.mode, cameraPositionState){ - val positionTarget = cameraPositionState.position.target ?: return@StaticLocationItem - state.eventSink( - ShareLocationEvent.ShareStaticLocation( - cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( - lat = positionTarget.latitude, - lon = positionTarget.longitude, - zoom = cameraPositionState.position.zoom, - ), - location = cameraPositionState.location?.let { - Location( - lat = it.latitude, - lon = it.longitude, - accuracy = it.accuracy, - ) - } - ) - ) - navigateUp() - } - if(state.canShareLiveLocation){ - LiveLocationItem { - state.eventSink(ShareLocationEvent.SelectLiveLocationDuration) - } - } - Spacer(modifier = Modifier.height(16.dp + navBarPadding)) - }, + MapBottomSheetScaffold( + cameraState = cameraState, modifier = modifier, - scaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded), - ), - sheetDragHandle = {}, + scaffoldState = scaffoldState, + sheetDragHandle = null, sheetSwipeEnabled = false, topBar = { TopAppBar( @@ -178,62 +134,102 @@ fun ShareLocationView( }, ) }, - ) { - Box( - modifier = Modifier - .padding(it) - .consumeWindowInsets(it), - contentAlignment = Alignment.Center - ) { - MapLibreMap( - styleUri = rememberTileStyleUrl(), - modifier = Modifier.fillMaxSize(), - cameraPositionState = cameraPositionState, - uiSettings = MapDefaults.uiSettings, - symbolManagerSettings = MapDefaults.symbolManagerSettings, - locationSettings = MapDefaults.locationSettings.copy( - locationEnabled = state.hasLocationPermission, - ), + sheetContent = { + BottomSheetContent( + cameraState = cameraState, + state = state, + userLocationState = userLocationState, + navigateUp = navigateUp ) - Icon( - resourceId = CommonDrawables.pin, - contentDescription = null, - tint = Color.Unspecified, - modifier = Modifier.centerBottomEdge(this), + }, + mapContent = { + UserLocation( + cameraState = cameraState, + locationState = userLocationState, + trackUserLocation = state.trackUserLocation ) - LocationFloatingActionButton( - isMapCenteredOnUser = state.mode == ShareLocationState.Mode.SenderLocation, - onClick = { state.eventSink(ShareLocationEvent.SwitchToMyLocationMode) }, + }, + overlayContent = { sheetPadding -> + Box( modifier = Modifier - .align(Alignment.BottomEnd) - .padding(end = 18.dp, bottom = 72.dp + navBarPadding), + .fillMaxSize() + .padding(sheetPadding) + ) { + Icon( + resourceId = CommonDrawables.pin, + contentDescription = null, + tint = Color.Unspecified, + modifier = Modifier.centerBottomEdge(this), + ) + } + LocationFloatingActionButton( + isMapCenteredOnUser = state.trackUserLocation, + onClick = { state.eventSink(ShareLocationEvent.StartTrackingUserPosition) }, + modifier = Modifier + .align(Alignment.TopEnd) + .padding(all = 16.dp), ) } + ) +} + +@Composable +private fun BottomSheetContent( + cameraState: CameraState, + state: ShareLocationState, + userLocationState: UserLocationState, + navigateUp: () -> Unit, +) { + Spacer(Modifier.height(20.dp)) + SharePinLocationItem( + onClick = { + val positionTarget = cameraState.position.target + state.eventSink( + ShareLocationEvent.ShareStaticLocation( + location = Location(lat = positionTarget.latitude, lon = positionTarget.longitude), + isPinned = true + ) + ) + navigateUp() + } + ) + ShareCurrentLocationItem( + onClick = { + val userLocation = userLocationState.location + if (state.hasLocationPermission) { + if (userLocation == null) { + // + } else { + state.eventSink( + ShareLocationEvent.ShareStaticLocation( + location = Location( + lat = userLocation.position.latitude, + lon = userLocation.position.longitude + ), + isPinned = false + ) + ) + navigateUp() + } + } + } + ) + if (state.canShareLiveLocation) { + ShareLiveLocationItem { + state.eventSink(ShareLocationEvent.ShowLiveLocationDurationPicker) + } } } @Composable -private fun StaticLocationItem( - mode: ShareLocationState.Mode, - cameraPositionState: CameraPositionState, - onClick: ()->Unit, +private fun ShareCurrentLocationItem( + onClick: () -> Unit, ) { ListItem( headlineContent = { - Text( - stringResource( - when (mode) { - ShareLocationState.Mode.PinLocation -> CommonStrings.screen_share_this_location_action - ShareLocationState.Mode.SenderLocation -> CommonStrings.screen_share_my_location_action - } - ) - ) + Text(stringResource(CommonStrings.screen_share_my_location_action)) }, - modifier = Modifier.clickable( - // target is null when the map hasn't loaded (or api key is wrong) so we disable the button - enabled = cameraPositionState.position.target != null, - onClick = onClick - ), + modifier = Modifier.clickable(onClick = onClick), leadingContent = ListItemContent.Icon( iconSource = IconSource.Vector(CompoundIcons.LocationNavigatorCentred()) ) @@ -241,7 +237,22 @@ private fun StaticLocationItem( } @Composable -private fun LiveLocationItem( +private fun SharePinLocationItem( + onClick: () -> Unit, +) { + ListItem( + headlineContent = { + Text(stringResource(CommonStrings.screen_share_this_location_action)) + }, + modifier = Modifier.clickable(onClick = onClick), + leadingContent = ListItemContent.Icon( + iconSource = IconSource.Vector(CompoundIcons.LocationNavigator()) + ) + ) +} + +@Composable +private fun ShareLiveLocationItem( onClick: () -> Unit, ) { ListItem( diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 6bc9e27bc6..f7d7a15207 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -8,15 +8,16 @@ package io.element.android.features.location.impl.show -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -24,31 +25,35 @@ 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.compound.tokens.generated.TypographyTokens -import io.element.android.features.location.api.internal.rememberTileStyleUrl +import io.element.android.features.location.impl.R import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton +import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold +import io.element.android.features.location.impl.common.ui.UserLocation import io.element.android.libraries.designsystem.components.button.BackButton 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.designsystem.theme.components.IconButton -import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar -import io.element.android.libraries.designsystem.utils.CommonDrawables -import io.element.android.libraries.maplibre.compose.CameraMode -import io.element.android.libraries.maplibre.compose.CameraMoveStartedReason -import io.element.android.libraries.maplibre.compose.IconAnchor -import io.element.android.libraries.maplibre.compose.MapLibreMap -import io.element.android.libraries.maplibre.compose.Symbol -import io.element.android.libraries.maplibre.compose.rememberCameraPositionState -import io.element.android.libraries.maplibre.compose.rememberSymbolState import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.collections.immutable.toImmutableMap -import org.maplibre.android.camera.CameraPosition -import org.maplibre.android.geometry.LatLng +import org.maplibre.compose.camera.CameraMoveReason +import org.maplibre.compose.camera.CameraPosition +import org.maplibre.compose.camera.rememberCameraState +import org.maplibre.compose.expressions.dsl.image +import org.maplibre.compose.layers.SymbolLayer +import org.maplibre.compose.location.DesiredAccuracy +import org.maplibre.compose.location.rememberDefaultLocationProvider +import org.maplibre.compose.location.rememberNullLocationProvider +import org.maplibre.compose.location.rememberUserLocationState +import org.maplibre.compose.sources.GeoJsonData +import org.maplibre.compose.sources.rememberGeoJsonSource +import org.maplibre.spatialk.geojson.Point +import org.maplibre.spatialk.geojson.Position +import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -71,33 +76,32 @@ fun ShowLocationView( ) } - val cameraPositionState = rememberCameraPositionState { - position = CameraPosition.Builder() - .target(LatLng(state.location.lat, state.location.lon)) - .zoom(MapDefaults.DEFAULT_ZOOM) - .build() + val cameraState = rememberCameraState( + firstPosition = CameraPosition( + target = Position(latitude = state.location.lat, longitude = state.location.lon), + zoom = MapDefaults.DEFAULT_ZOOM + ) + ) + val locationProvider = if (state.hasLocationPermission) { + rememberDefaultLocationProvider( + updateInterval = 1.minutes, + desiredAccuracy = DesiredAccuracy.Balanced, + minDistanceMeters = 50.0, + ) + } else { + rememberNullLocationProvider() } - - LaunchedEffect(state.isTrackMyLocation) { - when (state.isTrackMyLocation) { - false -> cameraPositionState.cameraMode = CameraMode.NONE - true -> { - cameraPositionState.position = CameraPosition.Builder() - .zoom(MapDefaults.DEFAULT_ZOOM) - .build() - cameraPositionState.cameraMode = CameraMode.TRACKING - } - } - } - - LaunchedEffect(cameraPositionState.isMoving) { - if (cameraPositionState.cameraMoveStartedReason == CameraMoveStartedReason.GESTURE) { + val userLocationState = rememberUserLocationState(locationProvider) + LaunchedEffect(cameraState.isCameraMoving) { + if (cameraState.moveReason == CameraMoveReason.GESTURE) { state.eventSink(ShowLocationEvents.TrackMyLocation(false)) } } - Scaffold( + MapBottomSheetScaffold( + cameraState = cameraState, modifier = modifier, + sheetPeekHeight = 80.dp, topBar = { TopAppBar( titleStr = stringResource(CommonStrings.screen_view_location_title), @@ -118,19 +122,7 @@ fun ShowLocationView( } ) }, - floatingActionButton = { - LocationFloatingActionButton( - isMapCenteredOnUser = state.isTrackMyLocation, - onClick = { state.eventSink(ShowLocationEvents.TrackMyLocation(true)) }, - ) - }, - ) { paddingValues -> - Column( - modifier = Modifier - .padding(paddingValues) - .consumeWindowInsets(paddingValues) - .fillMaxSize(), - ) { + sheetContent = { state.description?.let { Text( text = it, @@ -143,28 +135,40 @@ fun ShowLocationView( .padding(8.dp), ) } - - MapLibreMap( - styleUri = rememberTileStyleUrl(), - modifier = Modifier.fillMaxSize(), - images = mapOf(PIN_ID to CommonDrawables.pin).toImmutableMap(), - cameraPositionState = cameraPositionState, - uiSettings = MapDefaults.uiSettings, - symbolManagerSettings = MapDefaults.symbolManagerSettings, - locationSettings = MapDefaults.locationSettings.copy( - locationEnabled = state.hasLocationPermission, - ), - ) { - Symbol( - iconId = PIN_ID, - state = rememberSymbolState( - position = LatLng(state.location.lat, state.location.lon) - ), - iconAnchor = IconAnchor.BOTTOM, + }, + mapContent = { + UserLocation( + cameraState = cameraState, + locationState = userLocationState, + trackUserLocation = state.isTrackMyLocation + ) + val senderLocation = rememberGeoJsonSource( + data = GeoJsonData.Features( + Point( + Position( + latitude = state.location.lat, + longitude = state.location.lon + ) + ) ) - } + ) + val marker = painterResource(R.drawable.pin_small) + SymbolLayer( + id = "sender_location", + source = senderLocation, + iconImage = image(marker) + ) + }, + overlayContent = { + LocationFloatingActionButton( + isMapCenteredOnUser = state.isTrackMyLocation, + onClick = { state.eventSink(ShowLocationEvents.TrackMyLocation(true)) }, + modifier = Modifier + .align(Alignment.TopEnd) + .padding(all = 16.dp), + ) } - } + ) } @PreviewsDayNight @@ -175,5 +179,3 @@ internal fun ShowLocationViewPreview(@PreviewParameter(ShowLocationStateProvider onBackClick = {}, ) } - -private const val PIN_ID = "pin" From 222b9f0c9ef53de3f225c09af8410392275d5d19 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 26 Feb 2026 19:03:28 +0100 Subject: [PATCH 010/103] Raname UserLocation to UserLocationPuck --- .../impl/common/ui/{UserLocation.kt => UserLocationPuck.kt} | 2 +- .../features/location/impl/share/ShareLocationView.kt | 4 ++-- .../android/features/location/impl/show/ShowLocationView.kt | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/{UserLocation.kt => UserLocationPuck.kt} (98%) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt similarity index 98% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt index 9a5b6121b0..9d073f8942 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocation.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt @@ -18,7 +18,7 @@ import org.maplibre.compose.location.LocationTrackingEffect import org.maplibre.compose.location.UserLocationState @Composable -fun UserLocation( +fun UserLocationPuck( cameraState: CameraState, locationState: UserLocationState, trackUserLocation: Boolean, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 84829d4bf9..03638f8f90 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -41,7 +41,7 @@ import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold -import io.element.android.features.location.impl.common.ui.UserLocation +import io.element.android.features.location.impl.common.ui.UserLocationPuck import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -143,7 +143,7 @@ fun ShareLocationView( ) }, mapContent = { - UserLocation( + UserLocationPuck( cameraState = cameraState, locationState = userLocationState, trackUserLocation = state.trackUserLocation diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index f7d7a15207..d53895d273 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -8,9 +8,7 @@ package io.element.android.features.location.impl.show -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable @@ -31,7 +29,7 @@ import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold -import io.element.android.features.location.impl.common.ui.UserLocation +import io.element.android.features.location.impl.common.ui.UserLocationPuck import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -137,7 +135,7 @@ fun ShowLocationView( } }, mapContent = { - UserLocation( + UserLocationPuck( cameraState = cameraState, locationState = userLocationState, trackUserLocation = state.isTrackMyLocation From b4cf8c274e3b8a4f13289eaad1e644b7c2db2fbc Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 26 Feb 2026 22:07:30 +0100 Subject: [PATCH 011/103] Make sure we can display both Live and Static locations in ShowLocation --- .../location/api/ShowLocationEntryPoint.kt | 3 +- .../features/location/api/ShowLocationMode.kt | 28 +++++++ .../location/impl/show/ShowLocationNode.kt | 2 +- .../impl/show/ShowLocationPresenter.kt | 21 +++-- .../location/impl/show/ShowLocationState.kt | 5 +- .../impl/show/ShowLocationStateProvider.kt | 34 ++++++-- .../location/impl/show/ShowLocationView.kt | 83 ++++++++++++------- .../messages/impl/MessagesFlowNode.kt | 18 ++-- .../event/TimelineItemLocationContent.kt | 2 + .../TimelineItemContentMessageFactoryTest.kt | 7 +- .../api/timeline/item/event/MessageType.kt | 2 + .../matrix/impl/room/location/AssetType.kt | 12 ++- .../matrix/impl/timeline/RustTimeline.kt | 4 +- .../timeline/item/event/EventMessageMapper.kt | 8 +- .../impl/room/location/AssetTypeKtTest.kt | 4 +- .../reply/InReplyToDetailsProvider.kt | 2 +- 16 files changed, 168 insertions(+), 67 deletions(-) create mode 100644 features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationMode.kt diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationEntryPoint.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationEntryPoint.kt index 03693a7d68..c41d3aa6fc 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationEntryPoint.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationEntryPoint.kt @@ -15,8 +15,7 @@ import io.element.android.libraries.architecture.NodeInputs interface ShowLocationEntryPoint : FeatureEntryPoint { data class Inputs( - val location: Location, - val description: String?, + val mode: ShowLocationMode, ) : NodeInputs fun createNode( diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationMode.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationMode.kt new file mode 100644 index 0000000000..1227ddec46 --- /dev/null +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/ShowLocationMode.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Element Creations 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.location.api + +import android.os.Parcelable +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.location.AssetType +import kotlinx.parcelize.Parcelize + +sealed interface ShowLocationMode : Parcelable { + @Parcelize + data class Static( + val location: Location, + val senderName: String, + val senderId: UserId, + val senderAvatarUrl: String?, + val timestamp: Long, + val assetType: AssetType?, + ) : ShowLocationMode + + @Parcelize + data object Live : ShowLocationMode +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationNode.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationNode.kt index 86d7741752..f318851f99 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationNode.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationNode.kt @@ -40,7 +40,7 @@ class ShowLocationNode( } private val inputs: ShowLocationEntryPoint.Inputs = inputs() - private val presenter = presenterFactory.create(inputs.location, inputs.description) + private val presenter = presenterFactory.create(inputs.mode) @Composable override fun View(modifier: Modifier) { diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 3dcccef886..f402b8fac9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -18,7 +18,7 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject -import io.element.android.features.location.api.Location +import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.permissions.PermissionsEvents @@ -29,15 +29,14 @@ import io.element.android.libraries.core.meta.BuildMeta @AssistedInject class ShowLocationPresenter( - @Assisted private val location: Location, - @Assisted private val description: String?, + @Assisted private val mode: ShowLocationMode, permissionsPresenterFactory: PermissionsPresenter.Factory, private val locationActions: LocationActions, private val buildMeta: BuildMeta, ) : Presenter { @AssistedFactory fun interface Factory { - fun create(location: Location, description: String?): ShowLocationPresenter + fun create(mode: ShowLocationMode): ShowLocationPresenter } private val permissionsPresenter = permissionsPresenterFactory.create(MapDefaults.permissions) @@ -59,7 +58,16 @@ class ShowLocationPresenter( fun handleEvent(event: ShowLocationEvents) { when (event) { - ShowLocationEvents.Share -> locationActions.share(location, description) + ShowLocationEvents.Share -> { + when (mode) { + is ShowLocationMode.Static -> { + locationActions.share(mode.location, null) + } + ShowLocationMode.Live -> { + // TODO: Handle sharing for live locations + } + } + } is ShowLocationEvents.TrackMyLocation -> { if (event.enabled) { when { @@ -82,8 +90,7 @@ class ShowLocationPresenter( return ShowLocationState( permissionDialog = permissionDialog, - location = location, - description = description, + mode = mode, hasLocationPermission = permissionsState.isAnyGranted, isTrackMyLocation = isTrackMyLocation, appName = appName, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 96635d6df8..4eefa34053 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -8,12 +8,11 @@ package io.element.android.features.location.impl.show -import io.element.android.features.location.api.Location +import io.element.android.features.location.api.ShowLocationMode data class ShowLocationState( val permissionDialog: Dialog, - val location: Location, - val description: String?, + val mode: ShowLocationMode, val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, val appName: String, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 7d03a1ebb2..4941d8984d 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -10,6 +10,9 @@ package io.element.android.features.location.impl.show import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location +import io.element.android.features.location.api.ShowLocationMode +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.location.AssetType private const val APP_NAME = "ApplicationName" @@ -31,32 +34,47 @@ class ShowLocationStateProvider : PreviewParameterProvider { isTrackMyLocation = true, ), aShowLocationState( - description = "My favourite place!", + mode = aStaticLocationMode(senderName = "My favourite place!"), ), aShowLocationState( - description = "For some reason I decided to to write a small essay that wraps at just two lines!", + mode = aStaticLocationMode( + senderName = "For some reason I decided to write a small essay that wraps at just two lines!" + ), ), aShowLocationState( - description = "For some reason I decided to write a small essay in the location description. " + - "It is so long that it will wrap onto more than two lines!", + mode = ShowLocationMode.Live, ), ) } fun aShowLocationState( permissionDialog: ShowLocationState.Dialog = ShowLocationState.Dialog.None, - location: Location = Location(1.23, 2.34, 4f), - description: String? = null, + mode: ShowLocationMode = aStaticLocationMode(), hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, appName: String = APP_NAME, eventSink: (ShowLocationEvents) -> Unit = {}, ) = ShowLocationState( permissionDialog = permissionDialog, - location = location, - description = description, + mode = mode, hasLocationPermission = hasLocationPermission, isTrackMyLocation = isTrackMyLocation, appName = appName, eventSink = eventSink, ) + +fun aStaticLocationMode( + location: Location = Location(1.23, 2.34, 4f), + senderName: String = "Alice", + senderId: UserId = UserId("@alice:matrix.org"), + senderAvatarUrl: String? = null, + timestamp: Long = System.currentTimeMillis(), + assetType: AssetType? = null, +) = ShowLocationMode.Static( + location = location, + senderName = senderName, + senderId = senderId, + senderAvatarUrl = senderAvatarUrl, + timestamp = timestamp, + assetType = assetType, +) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index d53895d273..8e16ef7c5c 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -11,6 +11,9 @@ package io.element.android.features.location.impl.show import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetValue +import androidx.compose.material3.rememberBottomSheetScaffoldState +import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment @@ -23,6 +26,7 @@ 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.compound.tokens.generated.TypographyTokens +import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.R import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog @@ -74,12 +78,16 @@ fun ShowLocationView( ) } - val cameraState = rememberCameraState( - firstPosition = CameraPosition( - target = Position(latitude = state.location.lat, longitude = state.location.lon), + val initialPosition = when (val mode = state.mode) { + is ShowLocationMode.Static -> CameraPosition( + target = Position(latitude = mode.location.lat, longitude = mode.location.lon), zoom = MapDefaults.DEFAULT_ZOOM ) - ) + ShowLocationMode.Live -> CameraPosition( + zoom = MapDefaults.DEFAULT_ZOOM + ) + } + val cameraState = rememberCameraState(firstPosition = initialPosition) val locationProvider = if (state.hasLocationPermission) { rememberDefaultLocationProvider( updateInterval = 1.minutes, @@ -96,10 +104,13 @@ fun ShowLocationView( } } + val scaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState() + ) MapBottomSheetScaffold( + scaffoldState = scaffoldState, cameraState = cameraState, modifier = modifier, - sheetPeekHeight = 80.dp, topBar = { TopAppBar( titleStr = stringResource(CommonStrings.screen_view_location_title), @@ -121,17 +132,22 @@ fun ShowLocationView( ) }, sheetContent = { - state.description?.let { - Text( - text = it, - textAlign = TextAlign.Center, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - style = TypographyTokens.fontBodyMdRegular, - modifier = Modifier - .fillMaxWidth() - .padding(8.dp), - ) + when (val mode = state.mode) { + is ShowLocationMode.Static -> { + Text( + text = mode.senderName, + textAlign = TextAlign.Center, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + style = TypographyTokens.fontBodyMdRegular, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + ) + } + ShowLocationMode.Live -> { + // TODO: Show list of active live location sharers + } } }, mapContent = { @@ -140,22 +156,29 @@ fun ShowLocationView( locationState = userLocationState, trackUserLocation = state.isTrackMyLocation ) - val senderLocation = rememberGeoJsonSource( - data = GeoJsonData.Features( - Point( - Position( - latitude = state.location.lat, - longitude = state.location.lon + when (val mode = state.mode) { + is ShowLocationMode.Static -> { + val senderLocation = rememberGeoJsonSource( + data = GeoJsonData.Features( + Point( + Position( + latitude = mode.location.lat, + longitude = mode.location.lon + ) + ) ) ) - ) - ) - val marker = painterResource(R.drawable.pin_small) - SymbolLayer( - id = "sender_location", - source = senderLocation, - iconImage = image(marker) - ) + val marker = painterResource(R.drawable.pin_small) + SymbolLayer( + id = "sender_location", + source = senderLocation, + iconImage = image(marker) + ) + } + ShowLocationMode.Live -> { + // TODO: Show pins for all active live location sharers + } + } }, overlayContent = { LocationFloatingActionButton( 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 b28574cdbf..9ad7c48e36 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 @@ -28,10 +28,10 @@ import io.element.android.features.call.api.CallType import io.element.android.features.call.api.ElementCallEntryPoint import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint -import io.element.android.features.location.api.Location import io.element.android.features.location.api.LocationService import io.element.android.features.location.api.ShareLocationEntryPoint import io.element.android.features.location.api.ShowLocationEntryPoint +import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewNode @@ -75,6 +75,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.room.location.AssetType 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 @@ -148,7 +149,7 @@ class MessagesFlowNode( data class AttachmentPreview(val timelineMode: Timeline.Mode, val attachment: Attachment, val inReplyToEventId: EventId?) : NavTarget @Parcelize - data class LocationViewer(val location: Location, val description: String?) : NavTarget + data class LocationViewer(val mode: ShowLocationMode) : NavTarget @Parcelize data class EventDebugInfo(val eventId: EventId?, val debugInfo: TimelineItemDebugInfo) : NavTarget @@ -336,7 +337,7 @@ class MessagesFlowNode( createNode(buildContext, listOf(inputs)) } is NavTarget.LocationViewer -> { - val inputs = ShowLocationEntryPoint.Inputs(navTarget.location, navTarget.description) + val inputs = ShowLocationEntryPoint.Inputs(navTarget.mode) showLocationEntryPoint.createNode( parentNode = this, buildContext = buildContext, @@ -558,9 +559,16 @@ class MessagesFlowNode( ) } is TimelineItemLocationContent -> { - NavTarget.LocationViewer( + val mode = ShowLocationMode.Static( location = event.content.location, - description = event.content.description, + senderName = event.safeSenderName, + senderId = event.senderId, + senderAvatarUrl = event.senderAvatar.url, + timestamp = event.sentTimeMillis, + assetType = event.content.assetType, + ) + NavTarget.LocationViewer( + mode = mode ).takeIf { locationService.isServiceAvailable() } } else -> null diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt index 1114b2ab15..5547eb29c3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt @@ -9,11 +9,13 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.features.location.api.Location +import io.element.android.libraries.matrix.api.room.location.AssetType data class TimelineItemLocationContent( val body: String, val location: Location, val description: String? = null, + val assetType: AssetType? = null, ) : TimelineItemEventContent { override val type: String = "TimelineItemLocationContent" } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt index 9f23388ecb..24f8c30ab1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt @@ -41,6 +41,7 @@ import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.ThumbnailInfo import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.permalink.PermalinkData +import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType @@ -98,8 +99,9 @@ class TimelineItemContentMessageFactoryTest { @Test fun `test create LocationMessageType not null`() = runTest { val sut = createTimelineItemContentMessageFactory() + val assetType = AssetType.SENDER val result = sut.create( - content = createMessageContent(type = LocationMessageType("body", "geo:1,2", "description")), + content = createMessageContent(type = LocationMessageType("body", "geo:1,2", "description", assetType)), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, ) @@ -107,6 +109,7 @@ class TimelineItemContentMessageFactoryTest { body = "body", location = Location(lat = 1.0, lon = 2.0, accuracy = 0.0F), description = "description", + assetType = assetType, ) assertThat(result).isEqualTo(expected) } @@ -115,7 +118,7 @@ class TimelineItemContentMessageFactoryTest { fun `test create LocationMessageType null`() = runTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( - content = createMessageContent(type = LocationMessageType("body", "", null)), + content = createMessageContent(type = LocationMessageType("body", "", null, null)), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageType.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageType.kt index 6de2876f61..0cc5ca0ff7 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageType.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageType.kt @@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.VideoInfo +import io.element.android.libraries.matrix.api.room.location.AssetType @Immutable sealed interface MessageType @@ -55,6 +56,7 @@ data class LocationMessageType( val body: String, val geoUri: String, val description: String?, + val assetType: AssetType?, ) : MessageType data class AudioMessageType( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt index c7c2c88fcc..40a55cede1 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt @@ -9,8 +9,14 @@ package io.element.android.libraries.matrix.impl.room.location import io.element.android.libraries.matrix.api.room.location.AssetType +import org.matrix.rustcomponents.sdk.AssetType as RustAssetType -fun AssetType.toInner(): org.matrix.rustcomponents.sdk.AssetType = when (this) { - AssetType.SENDER -> org.matrix.rustcomponents.sdk.AssetType.SENDER - AssetType.PIN -> org.matrix.rustcomponents.sdk.AssetType.PIN +fun AssetType.into(): RustAssetType = when (this) { + AssetType.SENDER -> RustAssetType.SENDER + AssetType.PIN -> RustAssetType.PIN +} + +fun RustAssetType.into(): AssetType = when(this){ + RustAssetType.SENDER -> AssetType.SENDER + RustAssetType.PIN -> AssetType.PIN } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 0ee7239933..3996155871 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -32,7 +32,7 @@ import io.element.android.libraries.matrix.impl.media.MediaUploadHandlerImpl import io.element.android.libraries.matrix.impl.media.map import io.element.android.libraries.matrix.impl.poll.toInner import io.element.android.libraries.matrix.impl.room.RoomContentForwarder -import io.element.android.libraries.matrix.impl.room.location.toInner +import io.element.android.libraries.matrix.impl.room.location.into import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEventContentMapper import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTimelineItemMapper @@ -478,7 +478,7 @@ class RustTimeline( geoUri = geoUri, description = description, zoomLevel = zoomLevel?.toUByte(), - assetType = assetType?.toInner(), + assetType = assetType?.into(), repliedToEventId = inReplyToEventId?.value, ) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt index 813bf0ec11..d89d2766eb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageTy import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType import io.element.android.libraries.matrix.impl.media.map +import io.element.android.libraries.matrix.impl.room.location.into import io.element.android.libraries.matrix.impl.timeline.reply.InReplyToMapper import org.matrix.rustcomponents.sdk.InReplyToDetails import org.matrix.rustcomponents.sdk.MessageType @@ -112,7 +113,12 @@ class EventMessageMapper { ) } is RustMessageType.Location -> { - LocationMessageType(type.content.body, type.content.geoUri, type.content.description) + LocationMessageType( + body = type.content.body, + geoUri = type.content.geoUri, + description = type.content.description, + assetType = type.content.asset?.into() + ) } is MessageType.Other -> { OtherMessageType(type.msgtype, type.body) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetTypeKtTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetTypeKtTest.kt index 9b12d12a04..f20ae940cf 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetTypeKtTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetTypeKtTest.kt @@ -15,7 +15,7 @@ import org.junit.Test class AssetTypeKtTest { @Test fun toInner() { - assertThat(AssetType.SENDER.toInner()).isEqualTo(org.matrix.rustcomponents.sdk.AssetType.SENDER) - assertThat(AssetType.PIN.toInner()).isEqualTo(org.matrix.rustcomponents.sdk.AssetType.PIN) + assertThat(AssetType.SENDER.into()).isEqualTo(org.matrix.rustcomponents.sdk.AssetType.SENDER) + assertThat(AssetType.PIN.into()).isEqualTo(org.matrix.rustcomponents.sdk.AssetType.PIN) } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt index 0727b0b7ec..4b2f18a362 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt @@ -71,7 +71,7 @@ open class InReplyToDetailsProvider : PreviewParameterProvider ), aMessageContent( body = "Location", - type = LocationMessageType("Location", "geo:1,2", null), + type = LocationMessageType("Location", "geo:1,2", null, assetType = null), ), aMessageContent( body = "Notice", From a6e31b5c451d4a2d0a80f10e5e34fdf43ace1ea5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 26 Feb 2026 22:14:05 +0100 Subject: [PATCH 012/103] Use ListItem.onClick method --- .../features/location/impl/share/ShareLocationView.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 03638f8f90..f1e782cb26 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -229,7 +229,7 @@ private fun ShareCurrentLocationItem( headlineContent = { Text(stringResource(CommonStrings.screen_share_my_location_action)) }, - modifier = Modifier.clickable(onClick = onClick), + onClick = onClick, leadingContent = ListItemContent.Icon( iconSource = IconSource.Vector(CompoundIcons.LocationNavigatorCentred()) ) @@ -244,7 +244,7 @@ private fun SharePinLocationItem( headlineContent = { Text(stringResource(CommonStrings.screen_share_this_location_action)) }, - modifier = Modifier.clickable(onClick = onClick), + onClick = onClick, leadingContent = ListItemContent.Icon( iconSource = IconSource.Vector(CompoundIcons.LocationNavigator()) ) @@ -259,9 +259,7 @@ private fun ShareLiveLocationItem( headlineContent = { Text("Share live location") }, - modifier = Modifier.clickable( - onClick = onClick - ), + onClick = onClick, leadingContent = ListItemContent.Icon( iconSource = IconSource.Vector(CompoundIcons.LocationPinSolid()), tintColor = ElementTheme.colors.iconAccentPrimary, From f6c1ad47d76bb50be5e573db4bef392a040353c2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 27 Feb 2026 14:51:16 +0100 Subject: [PATCH 013/103] Fix MapBottomSheetScaffold paddings --- .../impl/common/ui/MapBottomSheetScaffold.kt | 25 +++++++++++++------ .../location/impl/show/ShowLocationView.kt | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt index 0a1b0cff9a..78364a6f4e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -7,15 +7,21 @@ package io.element.android.features.location.impl.common.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.only +import androidx.compose.foundation.layout.safeContent +import androidx.compose.foundation.layout.windowInsetsBottomHeight +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.material3.BottomSheetDefaults import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.ExperimentalMaterial3Api @@ -31,6 +37,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -39,13 +46,13 @@ import io.element.android.features.location.api.internal.rememberTileStyleUrl import io.element.android.features.location.impl.common.MapDefaults import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold -import kotlin.math.roundToInt import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState import org.maplibre.compose.map.MapOptions import org.maplibre.compose.map.MaplibreMap import org.maplibre.compose.style.BaseStyle import org.maplibre.compose.util.MaplibreComposable +import kotlin.math.roundToInt /** * A reusable scaffold component for map views with a bottom sheet. @@ -87,7 +94,8 @@ fun MapBottomSheetScaffold( ) { val density = LocalDensity.current - BoxWithConstraints(modifier = modifier.safeDrawingPadding()) { + val windowInsets = WindowInsets.safeContent.only(WindowInsetsSides.Horizontal) + BoxWithConstraints(modifier = modifier.windowInsetsPadding(windowInsets)) { val layoutHeightPx by rememberUpdatedState(constraints.maxHeight) val sheetPadding by remember { derivedStateOf { @@ -101,12 +109,12 @@ fun MapBottomSheetScaffold( LaunchedEffect(sheetPadding) { cameraState.position = cameraState.position.copy(padding = sheetPadding) } - BottomSheetScaffold( + modifier = Modifier, sheetPeekHeight = sheetPeekHeight, sheetContent = { sheetContent() - Spacer(modifier = Modifier.navigationBarsPadding()) + Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars)) }, scaffoldState = scaffoldState, sheetDragHandle = sheetDragHandle, @@ -115,9 +123,10 @@ fun MapBottomSheetScaffold( topBar = topBar, ) { val ornamentOptions = mapOptions.ornamentOptions.copy(padding = sheetPadding) - Box { + val mapOptions = mapOptions.copy(ornamentOptions = ornamentOptions) + Box{ MaplibreMap( - options = mapOptions.copy(ornamentOptions = ornamentOptions), + options = mapOptions, baseStyle = BaseStyle.Uri(rememberTileStyleUrl()), modifier = Modifier.fillMaxSize(), cameraState = cameraState, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 8e16ef7c5c..fc00f00c79 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -108,6 +108,7 @@ fun ShowLocationView( bottomSheetState = rememberStandardBottomSheetState() ) MapBottomSheetScaffold( + sheetPeekHeight = 180.dp, scaffoldState = scaffoldState, cameraState = cameraState, modifier = modifier, From 904657e86f9b0b7e8c5e5695d7a1f8464370dca7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 3 Mar 2026 21:45:16 +0100 Subject: [PATCH 014/103] Introduce LocationPinMarker --- .../components/LocationPinMarker.kt | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt new file mode 100644 index 0000000000..a7b25554b5 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2026 Element Creations 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.components + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.border +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.offset +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.Fill +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.components.avatar.avatarShape +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import kotlin.math.cos +import kotlin.math.sin + +/** + * Variants of location pin markers. + */ +sealed interface PinVariant { + data class UserLocation( + val avatarData: AvatarData, + val isLive: Boolean, + ) : PinVariant + + data object PinnedLocation : PinVariant + data object StaleLocation : PinVariant +} + +private val PIN_MARKER_WIDTH = 42.dp +private val PIN_MARKER_HEIGHT = (PIN_MARKER_WIDTH * 1.2f) +private val DOT_RADIUS = 6.dp +private val CONTENT_OFFSET = 5.dp + +/** + * A location pin marker composable that supports multiple variants. + * + * Based on Figma design: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=4665-2890&m=dev + */ +@Composable +fun LocationPinMarker( + variant: PinVariant, + modifier: Modifier = Modifier, +) { + val colors = LocationPinColors.fromVariant(variant) + Box( + modifier = modifier.size(width = PIN_MARKER_WIDTH, height = PIN_MARKER_HEIGHT), + ) { + // Draw the pin shape + Canvas( + modifier = Modifier.matchParentSize() + ) { + drawPinShape( + fillColor = colors.fill, + strokeColor = colors.stroke, + strokeWidth = 1.dp.toPx(), + ) + } + + val avatarSize = PIN_MARKER_WIDTH - CONTENT_OFFSET * 2 + val contentModifier = Modifier + .align(Alignment.TopCenter) + .offset(y = CONTENT_OFFSET) + + when (variant) { + is PinVariant.UserLocation -> { + Avatar( + avatarData = variant.avatarData, + forcedAvatarSize = avatarSize, + avatarType = AvatarType.User, + modifier = contentModifier + .border(width = 1.dp, color = colors.avatarStoke, shape = AvatarType.User.avatarShape()), + ) + } + PinVariant.PinnedLocation, PinVariant.StaleLocation -> { + Canvas( + modifier = contentModifier.size(avatarSize) + ) { + drawCircle( + color = colors.dotColor, + radius = DOT_RADIUS.toPx(), + center = center, + ) + } + } + } + } +} + +private data class LocationPinColors( + val fill: Color, + val stroke: Color, + val dotColor: Color, + val avatarStoke: Color, +) { + companion object { + @Composable + fun fromVariant(variant: PinVariant): LocationPinColors { + return when (variant) { + is PinVariant.UserLocation -> + if (variant.isLive) { + LocationPinColors( + fill = ElementTheme.colors.iconAccentPrimary, + stroke = ElementTheme.colors.bgCanvasDefault, + dotColor = Color.Transparent, + avatarStoke = ElementTheme.colors.bgCanvasDefault, + ) + } else { + LocationPinColors( + fill = ElementTheme.colors.bgCanvasDefault, + stroke = ElementTheme.colors.iconQuaternaryAlpha, + dotColor = Color.Transparent, + avatarStoke = ElementTheme.colors.iconQuaternaryAlpha, + ) + } + PinVariant.PinnedLocation -> LocationPinColors( + fill = ElementTheme.colors.bgCanvasDefault, + stroke = ElementTheme.colors.iconSecondaryAlpha, + dotColor = ElementTheme.colors.iconPrimary, + avatarStoke = Color.Transparent, + ) + PinVariant.StaleLocation -> LocationPinColors( + fill = ElementTheme.colors.bgSubtlePrimary, + stroke = ElementTheme.colors.borderInteractiveSecondary, + dotColor = ElementTheme.colors.iconDisabled, + avatarStoke = Color.Transparent, + ) + } + } + } +} + +/** + * Draws a teardrop-shaped pin with smooth curves. + * + * Based on SVG reference with dimensions 40x48 (ratio 1:1.2). + * Uses quadratic Bezier curves for smooth transitions from circle to tip. + */ +private fun DrawScope.drawPinShape( + fillColor: Color, + strokeColor: Color, + strokeWidth: Float, +) { + val width = size.width + val height = size.height + + val circleRadius = width / 2 - strokeWidth + val circleCenterX = width / 2 + val circleCenterY = width / 2 + + // The tip at the bottom + val tipX = width / 2 + val tipY = height - strokeWidth + + // Angle from the bottom of circle where it transitions to curves (in degrees) + val transitionAngleDeg = 65f + + val rightTransitionAngle = 90f - transitionAngleDeg + val leftTransitionAngle = 90f + transitionAngleDeg + + // Calculate transition points on the circle + val rightTransitionX = circleCenterX + circleRadius * cos(Math.toRadians(rightTransitionAngle.toDouble())).toFloat() + val rightTransitionY = circleCenterY + circleRadius * sin(Math.toRadians(rightTransitionAngle.toDouble())).toFloat() + val leftTransitionX = circleCenterX + circleRadius * cos(Math.toRadians(leftTransitionAngle.toDouble())).toFloat() + val leftTransitionY = circleCenterY + circleRadius * sin(Math.toRadians(leftTransitionAngle.toDouble())).toFloat() + + // Arc sweep: counter-clockwise over the top + val arcSweepAngle = -(360f - 2 * transitionAngleDeg) + + // For cubic Bezier: tangent direction at transition points + // Shorter tangent for smoother transition from circle + val tangentLength = (tipY - leftTransitionY) * 0.45f + + // Left side control points (from left transition to tip) + val leftTangentAngle = leftTransitionAngle - 90.0 + val leftC1X = leftTransitionX + tangentLength * cos(Math.toRadians(leftTangentAngle)).toFloat() + val leftC1Y = leftTransitionY + tangentLength * sin(Math.toRadians(leftTangentAngle)).toFloat() + // C2 control points - horizontal approach creates rounded tip + val tipOffset = 20f + val leftC2X = tipX - tipOffset + val leftC2Y = tipY - strokeWidth + // Right side control points (from tip to right transition) + val rightTangentAngle = rightTransitionAngle + 90.0 + val rightC1X = tipX + tipOffset + val rightC1Y = tipY - strokeWidth + val rightC2X = rightTransitionX + tangentLength * cos(Math.toRadians(rightTangentAngle)).toFloat() + val rightC2Y = rightTransitionY + tangentLength * sin(Math.toRadians(rightTangentAngle)).toFloat() + + val path = Path().apply { + moveTo(rightTransitionX, rightTransitionY) + arcTo( + rect = Rect( + center = Offset(circleCenterX, circleCenterY), + radius = circleRadius, + ), + startAngleDegrees = rightTransitionAngle, + sweepAngleDegrees = arcSweepAngle, + forceMoveTo = false, + ) + + // Cubic Bezier from left transition point to tip + cubicTo(leftC1X, leftC1Y, leftC2X, leftC2Y, tipX, tipY) + // Cubic Bezier from tip back to right transition point + cubicTo(rightC1X, rightC1Y, rightC2X, rightC2Y, rightTransitionX, rightTransitionY) + + close() + } + + drawPath(path = path, color = fillColor, style = Fill) + drawPath(path = path, color = strokeColor, style = Stroke(width = strokeWidth)) +} + +@PreviewsDayNight +@Composable +internal fun LocationPinMarkerPreview() = ElementPreview { + val sampleAvatarData = AvatarData( + id = "@alice:matrix.org", + name = "Alice", + url = null, + size = AvatarSize.SelectedUser + ) + + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + LocationPinMarker( + variant = PinVariant.UserLocation(avatarData = sampleAvatarData, isLive = false), + ) + LocationPinMarker( + variant = PinVariant.UserLocation(avatarData = sampleAvatarData, isLive = true), + ) + } + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + LocationPinMarker( + variant = PinVariant.PinnedLocation, + ) + LocationPinMarker( + variant = PinVariant.StaleLocation, + ) + } + } +} From ec1d6ebabb71f23fa016e46214adfd33b7269632 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 3 Mar 2026 21:56:45 +0100 Subject: [PATCH 015/103] Add current user to ShareLocationState --- .../features/location/impl/share/ShareLocationPresenter.kt | 6 ++++++ .../features/location/impl/share/ShareLocationState.kt | 3 +++ .../location/impl/share/ShareLocationStateProvider.kt | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index bd82b823f0..63d4b7ce8d 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -32,10 +32,13 @@ import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.CreateTimelineParams import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.launch @@ -50,6 +53,7 @@ class ShareLocationPresenter( private val locationActions: LocationActions, private val buildMeta: BuildMeta, private val featureFlagService: FeatureFlagService, + private val client: MatrixClient, ) : Presenter { @AssistedFactory fun interface Factory { @@ -69,6 +73,7 @@ class ShareLocationPresenter( var dialogState: ShareLocationState.Dialog by remember { mutableStateOf(ShareLocationState.Dialog.None) } + val currentUser by client.userProfile.collectAsState() val scope = rememberCoroutineScope() LaunchedEffect(permissionsState.permissions) { @@ -108,6 +113,7 @@ class ShareLocationPresenter( } return ShareLocationState( + currentUser = currentUser, dialogState = dialogState, trackUserLocation = trackUserPosition, hasLocationPermission = permissionsState.isAnyGranted, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 947d286c5e..547bb99856 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -8,7 +8,10 @@ package io.element.android.features.location.impl.share +import io.element.android.libraries.matrix.api.user.MatrixUser + data class ShareLocationState( + val currentUser: MatrixUser, val dialogState: Dialog, val trackUserLocation: Boolean, val hasLocationPermission: Boolean, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index 45a81af1df..0d3c448f15 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -9,6 +9,8 @@ package io.element.android.features.location.impl.share import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser private const val APP_NAME = "ApplicationName" @@ -50,12 +52,14 @@ class ShareLocationStateProvider : PreviewParameterProvider } private fun aShareLocationState( + currentUser: MatrixUser = MatrixUser(UserId("@user:matrix.org")), permissionDialog: ShareLocationState.Dialog, trackUserPosition: Boolean, hasLocationPermission: Boolean, canShareLiveLocation: Boolean = false, ): ShareLocationState { return ShareLocationState( + currentUser = currentUser, dialogState = permissionDialog, trackUserLocation = trackUserPosition, hasLocationPermission = hasLocationPermission, From f4bf596e3bfb28911fd1b6ae564581695b883ec5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 3 Mar 2026 22:05:17 +0100 Subject: [PATCH 016/103] Start using LocationPinMarker in Share and Show locations --- .../location/impl/common/ui/MapProjected.kt | 37 ++++++++++ .../location/impl/share/ShareLocationView.kt | 19 ++--- .../location/impl/show/ShowLocationView.kt | 70 +++++++------------ 3 files changed, 74 insertions(+), 52 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt new file mode 100644 index 0000000000..503e6ea3d7 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer +import org.maplibre.compose.camera.CameraState +import org.maplibre.spatialk.geojson.Position + +@Composable +fun MapProjected( + target: Position, + cameraState: CameraState, + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .graphicsLayer { + cameraState.position + val offset = cameraState.projection?.screenLocationFromPosition(target) + if (offset != null) { + translationX = offset.x.toPx() - size.width / 2 + translationY = offset.y.toPx() - size.height + } + } + ) { + content() + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index f1e782cb26..02b209ae43 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -8,7 +8,6 @@ package io.element.android.features.location.impl.share -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer @@ -28,7 +27,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -42,18 +40,20 @@ import io.element.android.features.location.impl.common.PermissionRationaleDialo import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck +import io.element.android.libraries.designsystem.components.LocationPinMarker +import io.element.android.libraries.designsystem.components.PinVariant +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.RadioButtonListItem 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.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar -import io.element.android.libraries.designsystem.utils.CommonDrawables +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition @@ -155,10 +155,13 @@ fun ShareLocationView( .fillMaxSize() .padding(sheetPadding) ) { - Icon( - resourceId = CommonDrawables.pin, - contentDescription = null, - tint = Color.Unspecified, + val variant = if (state.trackUserLocation) { + PinVariant.UserLocation(isLive = false, avatarData = state.currentUser.getAvatarData(AvatarSize.SelectedUser)) + } else { + PinVariant.PinnedLocation + } + LocationPinMarker( + variant = variant, modifier = Modifier.centerBottomEdge(this), ) } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index fc00f00c79..69ac04e0c5 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -9,6 +9,7 @@ package io.element.android.features.location.impl.show import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue @@ -18,22 +19,26 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign 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.compound.tokens.generated.TypographyTokens import io.element.android.features.location.api.ShowLocationMode -import io.element.android.features.location.impl.R import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold +import io.element.android.features.location.impl.common.ui.MapProjected import io.element.android.features.location.impl.common.ui.UserLocationPuck +import io.element.android.libraries.designsystem.components.LocationPinMarker +import io.element.android.libraries.designsystem.components.PinVariant +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -41,19 +46,15 @@ import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.ui.strings.CommonStrings import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.rememberCameraState -import org.maplibre.compose.expressions.dsl.image -import org.maplibre.compose.layers.SymbolLayer import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.rememberDefaultLocationProvider import org.maplibre.compose.location.rememberNullLocationProvider import org.maplibre.compose.location.rememberUserLocationState -import org.maplibre.compose.sources.GeoJsonData -import org.maplibre.compose.sources.rememberGeoJsonSource -import org.maplibre.spatialk.geojson.Point import org.maplibre.spatialk.geojson.Position import kotlin.time.Duration.Companion.minutes @@ -105,10 +106,9 @@ fun ShowLocationView( } val scaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = rememberStandardBottomSheetState() + bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false, initialValue = SheetValue.Hidden) ) MapBottomSheetScaffold( - sheetPeekHeight = 180.dp, scaffoldState = scaffoldState, cameraState = cameraState, modifier = modifier, @@ -132,56 +132,38 @@ fun ShowLocationView( } ) }, - sheetContent = { - when (val mode = state.mode) { - is ShowLocationMode.Static -> { - Text( - text = mode.senderName, - textAlign = TextAlign.Center, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - style = TypographyTokens.fontBodyMdRegular, - modifier = Modifier - .fillMaxWidth() - .padding(8.dp), - ) - } - ShowLocationMode.Live -> { - // TODO: Show list of active live location sharers - } - } - }, mapContent = { UserLocationPuck( cameraState = cameraState, locationState = userLocationState, trackUserLocation = state.isTrackMyLocation ) + }, + overlayContent = { when (val mode = state.mode) { is ShowLocationMode.Static -> { - val senderLocation = rememberGeoJsonSource( - data = GeoJsonData.Features( - Point( - Position( - latitude = mode.location.lat, - longitude = mode.location.lon - ) - ) + val pinVariant = if (mode.assetType == AssetType.PIN) { + PinVariant.PinnedLocation + } else { + PinVariant.UserLocation( + avatarData = AvatarData(mode.senderId.value, mode.senderName, mode.senderAvatarUrl, AvatarSize.UserListItem), + isLive = false ) + } + val position = Position( + latitude = mode.location.lat, + longitude = mode.location.lon ) - val marker = painterResource(R.drawable.pin_small) - SymbolLayer( - id = "sender_location", - source = senderLocation, - iconImage = image(marker) - ) + MapProjected(target = position, cameraState = cameraState) { + LocationPinMarker(variant = pinVariant) + } } ShowLocationMode.Live -> { // TODO: Show pins for all active live location sharers } } - }, - overlayContent = { + + LocationFloatingActionButton( isMapCenteredOnUser = state.isTrackMyLocation, onClick = { state.eventSink(ShowLocationEvents.TrackMyLocation(true)) }, From 046d135e4b2246f7f83b18367efb87c865d09141 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 3 Mar 2026 22:22:02 +0100 Subject: [PATCH 017/103] Introduce LiveLocationContent for the timeline (needs sdk) --- .../features/location/api/StaticMapView.kt | 11 ++- .../internal/MapTilerStaticMapUrlBuilder.kt | 2 +- .../impl/timeline/TimelineStateProvider.kt | 4 +- .../event/TimelineItemLocationView.kt | 35 ++++---- .../event/TimelineItemContentFactory.kt | 25 +++++- .../TimelineItemContentMessageFactory.kt | 22 +++++- .../impl/timeline/groups/Groupability.kt | 4 +- .../event/TimelineItemEventContentProvider.kt | 3 +- .../event/TimelineItemLocationContent.kt | 42 ++++++++++ .../TimelineItemLocationContentProvider.kt | 21 ++++- .../impl/fixtures/MessageEventFixtures.kt | 4 +- .../TimelineItemContentMessageFactoryTest.kt | 79 +++++++++++++------ .../groups/TimelineItemGrouperTest.kt | 4 +- .../impl/DefaultRoomLatestEventFormatter.kt | 5 ++ .../impl/DefaultTimelineEventFormatter.kt | 2 + .../api/room/location/LiveLocationInfo.kt | 15 ++++ .../api/timeline/item/event/EventContent.kt | 11 +++ .../reply/InReplyToDetailsProvider.kt | 4 +- .../ui/messages/reply/InReplyToMetadata.kt | 22 +++--- .../impl/datasource/EventItemFactory.kt | 2 + 20 files changed, 235 insertions(+), 82 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt index c58cadd66b..7d7752ba62 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt @@ -32,6 +32,8 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.api.internal.StaticMapPlaceholder import io.element.android.features.location.api.internal.StaticMapUrlBuilder import io.element.android.features.location.api.internal.centerBottomEdge +import io.element.android.libraries.designsystem.components.LocationPinMarker +import io.element.android.libraries.designsystem.components.PinVariant 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 @@ -45,6 +47,7 @@ fun StaticMapView( lat: Double, lon: Double, zoom: Double, + pinVariant: PinVariant, contentDescription: String?, modifier: Modifier = Modifier, darkMode: Boolean = !ElementTheme.isLightTheme, @@ -95,12 +98,7 @@ fun StaticMapView( // We apply ContentScale.Fit to scale the image to fill the AsyncImage should this be the case. contentScale = ContentScale.Fit, ) - Icon( - resourceId = CommonDrawables.pin, - contentDescription = null, - tint = Color.Unspecified, - modifier = Modifier.centerBottomEdge(this), - ) + LocationPinMarker(variant = pinVariant, modifier = Modifier.centerBottomEdge(this)) } else { StaticMapPlaceholder( showProgress = collectedState.value.isLoading(), @@ -127,6 +125,7 @@ internal fun StaticMapViewPreview() = ElementPreview { lon = 0.0, zoom = 0.0, contentDescription = null, + pinVariant = PinVariant.PinnedLocation, modifier = Modifier.size(400.dp), ) } diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilder.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilder.kt index 839cda0237..666ca07a08 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilder.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilder.kt @@ -58,7 +58,7 @@ internal class MapTilerStaticMapUrlBuilder( // image smaller than the available space in pixels. // The resulting image will have to be scaled to fit the available space in order // to keep the perceived content size constant at the expense of sharpness. - return "$baseUrl/$mapId/static/$lon,$lat,$finalZoom/${finalWidth}x${finalHeight}$scale.webp?key=$apiKey&attribution=bottomleft" + return "$baseUrl/$mapId/static/$lon,$lat,$finalZoom/${finalWidth}x${finalHeight}$scale.webp?key=$apiKey&attribution=topright" } override fun isServiceAvailable() = apiKey.isNotEmpty() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt index adfaa93cce..184acf1386 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt @@ -39,7 +39,7 @@ import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugIn import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails -import io.element.android.libraries.matrix.ui.messages.reply.aProfileTimelineDetailsReady +import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -166,7 +166,7 @@ internal fun aTimelineItemEvent( isMine = isMine, isEditable = isEditable, canBeRepliedTo = canBeRepliedTo, - senderProfile = aProfileTimelineDetailsReady( + senderProfile = aProfileDetailsReady( displayName = senderDisplayName, displayNameAmbiguous = displayNameAmbiguous, ), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt index 9ebe35a51b..b5c0152685 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt @@ -8,10 +8,8 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.PreviewParameter @@ -19,33 +17,28 @@ import androidx.compose.ui.unit.dp import io.element.android.features.location.api.StaticMapView import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContentProvider +import io.element.android.libraries.designsystem.components.PinVariant +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize 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 @Composable fun TimelineItemLocationView( content: TimelineItemLocationContent, modifier: Modifier = Modifier, ) { - Column(modifier = modifier.fillMaxWidth()) { - content.description?.let { - Text( - text = it, - modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp), - ) - } - - StaticMapView( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 188.dp), - lat = content.location.lat, - lon = content.location.lon, - zoom = 15.0, - contentDescription = content.body - ) - } + StaticMapView( + modifier = modifier + .fillMaxWidth() + .heightIn(max = 188.dp), + pinVariant = content.pinVariant, + lat = content.location.lat, + lon = content.location.lon, + zoom = 15.0, + contentDescription = content.body + ) } @PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt index 31cf689ef8..2b5c0fa98a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt @@ -9,8 +9,10 @@ package io.element.android.features.messages.impl.timeline.factories.event import dev.zacsweers.metro.Inject +import io.element.android.features.location.api.Location import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent import io.element.android.libraries.matrix.api.core.EventId @@ -22,6 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventTimeline import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent @@ -70,10 +73,10 @@ class TimelineItemContentFactory( is FailedToParseMessageLikeContent -> failedToParseMessageFactory.create(itemContent) is FailedToParseStateContent -> failedToParseStateFactory.create(itemContent) is MessageContent -> { - val senderDisambiguatedDisplayName = senderProfile.getDisambiguatedDisplayName(sender) messageFactory.create( + senderId = sender, + senderProfile = senderProfile, content = itemContent, - senderDisambiguatedDisplayName = senderDisambiguatedDisplayName, eventId = eventId, ) } @@ -96,6 +99,24 @@ class TimelineItemContentFactory( is UnableToDecryptContent -> utdFactory.create(itemContent) is CallNotifyContent -> TimelineItemRtcNotificationContent() is UnknownContent -> TimelineItemUnknownContent + is LiveLocationContent -> { + val lastKnownLocation = itemContent.locations.mapNotNull { beacon -> + Location.fromGeoUri(beacon.geoUri) + }.lastOrNull() + if (lastKnownLocation != null) { + TimelineItemLocationContent( + body = itemContent.body.trimEnd(), + description = itemContent.description?.trimEnd(), + assetType = itemContent.assetType, + senderId = sender, + senderProfile = senderProfile, + location = lastKnownLocation, + mode = TimelineItemLocationContent.Mode.Live(isActive = itemContent.isLive) + ) + } else { + TimelineItemUnknownContent + } + } } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index 1db6ad304c..829c11df6e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -29,8 +29,13 @@ import io.element.android.features.messages.impl.utils.TextPillificationHelper import io.element.android.libraries.androidutils.filesize.FileSizeFormatter import io.element.android.libraries.androidutils.text.safeLinkify import io.element.android.libraries.core.mimetype.MimeTypes +import io.element.android.libraries.designsystem.components.PinVariant +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.core.EventId +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkParser +import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -39,10 +44,13 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessa import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType import io.element.android.libraries.matrix.api.timeline.item.event.OtherMessageType +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessageType import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType +import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl +import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName import io.element.android.libraries.matrix.ui.messages.toHtmlDocument import io.element.android.libraries.mediaviewer.api.util.FileExtensionExtractor import kotlinx.collections.immutable.persistentListOf @@ -65,11 +73,13 @@ class TimelineItemContentMessageFactory( ) { fun create( content: MessageContent, - senderDisambiguatedDisplayName: String, + senderId: UserId, + senderProfile: ProfileDetails, eventId: EventId?, ): TimelineItemEventContent { return when (val messageType = content.type) { is EmoteMessageType -> { + val senderDisambiguatedDisplayName = senderProfile.getDisambiguatedDisplayName(senderId) val emoteBody = "* $senderDisambiguatedDisplayName ${messageType.body.trimEnd()}" val dom = messageType.formatted?.toHtmlDocument( permalinkParser = permalinkParser, @@ -135,8 +145,8 @@ class TimelineItemContentMessageFactory( } is LocationMessageType -> { val location = Location.fromGeoUri(messageType.geoUri) + val body = messageType.body.trimEnd() if (location == null) { - val body = messageType.body.trimEnd() TimelineItemTextContent( body = body, htmlDocument = null, @@ -145,9 +155,13 @@ class TimelineItemContentMessageFactory( ) } else { TimelineItemLocationContent( - body = messageType.body.trimEnd(), + body = body, location = location, - description = messageType.description + description = messageType.description, + senderId = senderId, + senderProfile = senderProfile, + assetType = messageType.assetType, + mode = TimelineItemLocationContent.Mode.Static ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt index 12c457175f..6f369417dd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt @@ -31,6 +31,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.CallNotifyCon import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent @@ -81,7 +82,8 @@ internal fun MatrixTimelineItem.Event.canBeDisplayedInBubbleBlock(): Boolean { RedactedContent, is StickerContent, is PollContent, - is UnableToDecryptContent -> true + is UnableToDecryptContent, + is LiveLocationContent -> true // Can't be grouped is FailedToParseStateContent, is ProfileChangeContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt index ac93a0ac4f..017fba1902 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt @@ -28,7 +28,8 @@ class TimelineItemEventContentProvider : PreviewParameterProvider { + if (mode.isActive) { + PinVariant.UserLocation(avatarData = senderAvatar(), isLive = true) + } else { + PinVariant.StaleLocation + } + } + Mode.Static -> { + when (assetType) { + AssetType.PIN -> PinVariant.PinnedLocation + AssetType.SENDER, + null -> PinVariant.UserLocation(avatarData = senderAvatar(), isLive = false) + } + } + } + + private fun senderAvatar() = AvatarData( + senderId.value, + name = senderProfile.getDisplayName(), + url = senderProfile.getAvatarUrl(), + // Size is irrelevant as the PinMarker will override anyway. + size = AvatarSize.TimelineSender + ) + + sealed interface Mode { + data object Static : Mode + data class Live(val isActive: Boolean) : Mode + } + override val type: String = "TimelineItemLocationContent" } + diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt index 0fd3f5f41b..07ab392f1e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt @@ -10,21 +10,34 @@ package io.element.android.features.messages.impl.timeline.model.event import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails +import io.element.android.libraries.matrix.ui.components.aMatrixUser +import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady open class TimelineItemLocationContentProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aTimelineItemLocationContent(), - aTimelineItemLocationContent("This is a description!"), + aTimelineItemLocationContent(mode = TimelineItemLocationContent.Mode.Live(isActive = true)), + aTimelineItemLocationContent(mode = TimelineItemLocationContent.Mode.Live(isActive = false)), ) } -fun aTimelineItemLocationContent(description: String? = null) = TimelineItemLocationContent( - body = "User location geo:52.2445,0.7186;u=5000", +fun aTimelineItemLocationContent( + body: String = "", + senderId: UserId = UserId("@sender:matrix.org"), + senderProfile: ProfileDetails = aProfileDetailsReady(), + mode: TimelineItemLocationContent.Mode = TimelineItemLocationContent.Mode.Static, +) = TimelineItemLocationContent( + body = body, location = Location( lat = 52.2445, lon = 0.7186, accuracy = 5000f, ), - description = description, + senderId = senderId, + senderProfile = senderProfile, + mode = mode ) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt index 516cd9ea77..1b9394f2ee 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt @@ -31,7 +31,7 @@ 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.core.FakeSendHandle import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails -import io.element.android.libraries.matrix.ui.messages.reply.aProfileTimelineDetailsReady +import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady import kotlinx.collections.immutable.toImmutableList internal fun aMessageEvent( @@ -52,7 +52,7 @@ internal fun aMessageEvent( eventId = eventId, transactionId = transactionId, senderId = A_USER_ID, - senderProfile = aProfileTimelineDetailsReady(displayName = A_USER_NAME), + senderProfile = aProfileDetailsReady(displayName = A_USER_NAME), senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME, size = AvatarSize.TimelineSender), content = content, sentTime = "", diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt index 24f8c30ab1..957b01d1ed 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt @@ -60,8 +60,10 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageTy import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.media.aMediaSource import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser +import io.element.android.libraries.matrix.test.timeline.aProfileDetails import io.element.android.libraries.matrix.test.timeline.aStickerContent import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH import io.element.android.libraries.mediaviewer.test.util.FileExtensionExtractorWithoutValidation @@ -84,7 +86,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = OtherMessageType(msgType = "a_type", body = "body")), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemTextContent( @@ -102,14 +105,18 @@ class TimelineItemContentMessageFactoryTest { val assetType = AssetType.SENDER val result = sut.create( content = createMessageContent(type = LocationMessageType("body", "geo:1,2", "description", assetType)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemLocationContent( body = "body", - location = Location(lat = 1.0, lon = 2.0, accuracy = 0.0F), + location = Location(lat = 1.0, lon = 2.0, accuracy = null), description = "description", assetType = assetType, + mode = TimelineItemLocationContent.Mode.Static, + senderId = A_USER_ID, + senderProfile = aProfileDetails(), ) assertThat(result).isEqualTo(expected) } @@ -119,7 +126,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = LocationMessageType("body", "", null, null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemTextContent( @@ -136,7 +144,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = TextMessageType("body", null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemTextContent( @@ -153,7 +162,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = TextMessageType("https://www.example.org", null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) as TimelineItemTextContent val expected = TimelineItemTextContent( @@ -200,7 +210,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, expected.toString()) ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(expected) @@ -218,7 +229,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.UNKNOWN, "formatted") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("body")) @@ -229,7 +241,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = VideoMessageType("filename", null, null, MediaSource("url"), null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemVideoContent( @@ -282,7 +295,8 @@ class TimelineItemContentMessageFactoryTest { ), isEdited = true, ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemVideoContent( @@ -312,7 +326,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = AudioMessageType("filename", null, null, MediaSource("url"), null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemAudioContent( @@ -348,7 +363,8 @@ class TimelineItemContentMessageFactoryTest { ), isEdited = true, ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemAudioContent( @@ -371,7 +387,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = VoiceMessageType("filename", null, null, MediaSource("url"), null, null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemVoiceContent( @@ -413,7 +430,8 @@ class TimelineItemContentMessageFactoryTest { ), isEdited = true, ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemVoiceContent( @@ -438,7 +456,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = ImageMessageType("filename", "body", null, MediaSource("url"), null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemImageContent( @@ -518,7 +537,8 @@ class TimelineItemContentMessageFactoryTest { ), isEdited = true, ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemImageContent( @@ -547,7 +567,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = FileMessageType("filename", null, null, MediaSource("url"), null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemFileContent( @@ -589,7 +610,8 @@ class TimelineItemContentMessageFactoryTest { ), isEdited = true, ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemFileContent( @@ -612,7 +634,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = NoticeMessageType("body", null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) val expected = TimelineItemNoticeContent( @@ -634,7 +657,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, "formatted") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) (result as TimelineItemNoticeContent).formattedBody.assertSpannedEquals(SpannedString("formatted")) @@ -645,7 +669,8 @@ class TimelineItemContentMessageFactoryTest { val sut = createTimelineItemContentMessageFactory() val result = sut.create( content = createMessageContent(type = EmoteMessageType("body", null)), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails("Bob"), eventId = AN_EVENT_ID, ) val expected = TimelineItemEmoteContent( @@ -667,7 +692,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, "formatted") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails("Bob"), eventId = AN_EVENT_ID, ) @@ -693,7 +719,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, "Test me@matrix.org") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) (result as TimelineItemTextContent).formattedBody.assertSpannedEquals(expectedSpanned) @@ -718,7 +745,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, "Test https://www.example.org") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) (result as TimelineItemTextContent).formattedBody.assertSpannedEquals(expectedSpanned) @@ -744,7 +772,8 @@ class TimelineItemContentMessageFactoryTest { formatted = FormattedBody(MessageFormat.HTML, "Test https://www.example.org") ) ), - senderDisambiguatedDisplayName = "Bob", + senderId = A_USER_ID, + senderProfile = aProfileDetails(), eventId = AN_EVENT_ID, ) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt index 7a7d4cdfd4..726646f5e9 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt @@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSen import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.core.FakeSendHandle -import io.element.android.libraries.matrix.ui.messages.reply.aProfileTimelineDetailsReady +import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady import kotlinx.collections.immutable.toImmutableList import org.junit.Test @@ -34,7 +34,7 @@ class TimelineItemGrouperTest { id = UniqueId("0"), senderId = A_USER_ID, senderAvatar = anAvatarData(), - senderProfile = aProfileTimelineDetailsReady(displayName = ""), + senderProfile = aProfileDetailsReady(displayName = ""), content = TimelineItemStateEventContent(body = "a state event"), reactionsState = aTimelineItemReactions(count = 0), readReceiptState = TimelineItemReadReceipts(emptyList().toImmutableList()), diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt index 009547f9eb..68dd4cd332 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParse import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.MessageType @@ -115,6 +116,10 @@ class DefaultRoomLatestEventFormatter( val message = sp.getString(CommonStrings.common_unsupported_event) message.prefixIfNeeded(senderDisambiguatedDisplayName, isDmRoom, isOutgoing) } + is LiveLocationContent -> { + val message = sp.getString(CommonStrings.common_shared_location) + message.prefixIfNeeded(senderDisambiguatedDisplayName, isDmRoom, isOutgoing) + } is LegacyCallInviteContent -> sp.getString(CommonStrings.common_unsupported_call) is CallNotifyContent -> sp.getString(CommonStrings.common_call_started) }?.take(DEFAULT_SAFE_LENGTH) diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultTimelineEventFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultTimelineEventFormatter.kt index 9657f87bd0..ff5cce7a59 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultTimelineEventFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultTimelineEventFormatter.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventTimeline import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent @@ -69,6 +70,7 @@ class DefaultTimelineEventFormatter( is MessageContent, is FailedToParseMessageLikeContent, is FailedToParseStateContent, + is LiveLocationContent, is UnknownContent -> { if (buildMeta.isDebuggable) { error("You should not use this formatter for this event content: $content") diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt new file mode 100644 index 0000000000..50b5a0ec82 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2026 Element Creations 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.room.location + +data class LiveLocationInfo( + val description: String?, + val geoUri: String, + val timestamp: Long, +) + diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index b6ed7dc602..e7b61e8dd6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -14,6 +14,8 @@ import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.poll.PollAnswer import io.element.android.libraries.matrix.api.poll.PollKind +import io.element.android.libraries.matrix.api.room.location.AssetType +import io.element.android.libraries.matrix.api.room.location.LiveLocationInfo import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -102,6 +104,15 @@ data class FailedToParseStateContent( val error: String ) : EventContent +data class LiveLocationContent( + val body: String, + val isLive: Boolean, + val description: String?, + val timeout: Long, + val assetType: AssetType?, + val locations: List, +): EventContent + data object LegacyCallInviteContent : EventContent data object CallNotifyContent : EventContent diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt index 4b2f18a362..5ddf57b723 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt @@ -152,13 +152,13 @@ private fun aInReplyToDetails( eventId = EventId("\$event"), eventContent = eventContent, senderId = UserId("@Sender:domain"), - senderProfile = aProfileTimelineDetailsReady( + senderProfile = aProfileDetailsReady( displayNameAmbiguous = displayNameAmbiguous, ), textContent = (eventContent as? MessageContent)?.body.orEmpty(), ) -fun aProfileTimelineDetailsReady( +fun aProfileDetailsReady( displayName: String? = "Sender", displayNameAmbiguous: Boolean = false, avatarUrl: String? = null, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadata.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadata.kt index 4d0a0f045b..9e5e468cd9 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadata.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadata.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParse import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent @@ -32,6 +33,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageT import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType +import io.element.android.libraries.matrix.ui.messages.reply.InReplyToMetadata.Text +import io.element.android.libraries.matrix.ui.messages.reply.InReplyToMetadata.Thumbnail import io.element.android.libraries.ui.strings.CommonStrings @Immutable @@ -60,7 +63,7 @@ internal sealed interface InReplyToMetadata { @Composable internal fun InReplyToDetails.Ready.metadata(hideImage: Boolean): InReplyToMetadata? = when (eventContent) { is MessageContent -> when (val type = eventContent.type) { - is ImageMessageType -> InReplyToMetadata.Thumbnail( + is ImageMessageType -> Thumbnail( AttachmentThumbnailInfo( thumbnailSource = (type.info?.thumbnailSource ?: type.source).takeUnless { hideImage }, textContent = eventContent.body, @@ -68,7 +71,7 @@ internal fun InReplyToDetails.Ready.metadata(hideImage: Boolean): InReplyToMetad blurHash = type.info?.blurhash, ) ) - is VideoMessageType -> InReplyToMetadata.Thumbnail( + is VideoMessageType -> Thumbnail( AttachmentThumbnailInfo( thumbnailSource = type.info?.thumbnailSource?.takeUnless { hideImage }, textContent = eventContent.body, @@ -76,34 +79,34 @@ internal fun InReplyToDetails.Ready.metadata(hideImage: Boolean): InReplyToMetad blurHash = type.info?.blurhash, ) ) - is FileMessageType -> InReplyToMetadata.Thumbnail( + is FileMessageType -> Thumbnail( AttachmentThumbnailInfo( thumbnailSource = type.info?.thumbnailSource?.takeUnless { hideImage }, textContent = eventContent.body, type = AttachmentThumbnailType.File, ) ) - is LocationMessageType -> InReplyToMetadata.Thumbnail( + is LocationMessageType -> Thumbnail( AttachmentThumbnailInfo( textContent = stringResource(CommonStrings.common_shared_location), type = AttachmentThumbnailType.Location, ) ) - is AudioMessageType -> InReplyToMetadata.Thumbnail( + is AudioMessageType -> Thumbnail( AttachmentThumbnailInfo( textContent = eventContent.body, type = AttachmentThumbnailType.Audio, ) ) - is VoiceMessageType -> InReplyToMetadata.Thumbnail( + is VoiceMessageType -> Thumbnail( AttachmentThumbnailInfo( textContent = stringResource(CommonStrings.common_voice_message), type = AttachmentThumbnailType.Voice, ) ) - else -> InReplyToMetadata.Text(textContent ?: eventContent.body) + else -> Text(textContent ?: eventContent.body) } - is StickerContent -> InReplyToMetadata.Thumbnail( + is StickerContent -> Thumbnail( AttachmentThumbnailInfo( thumbnailSource = eventContent.source.takeUnless { hideImage }, textContent = eventContent.body, @@ -111,7 +114,7 @@ internal fun InReplyToDetails.Ready.metadata(hideImage: Boolean): InReplyToMetad blurHash = eventContent.info.blurhash, ) ) - is PollContent -> InReplyToMetadata.Thumbnail( + is PollContent -> Thumbnail( AttachmentThumbnailInfo( textContent = eventContent.question, type = AttachmentThumbnailType.Poll, @@ -127,5 +130,6 @@ internal fun InReplyToDetails.Ready.metadata(hideImage: Boolean): InReplyToMetad UnknownContent, is LegacyCallInviteContent, is CallNotifyContent, + is LiveLocationContent, null -> null } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt index edbf9dc51e..67b73d616d 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParse import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInviteContent +import io.element.android.libraries.matrix.api.timeline.item.event.LiveLocationContent import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType @@ -75,6 +76,7 @@ class EventItemFactory( is StateContent, is StickerContent, is UnableToDecryptContent, + is LiveLocationContent, UnknownContent -> { Timber.w("Should not happen: ${content.javaClass.simpleName}") null From ba89201f37dee2e7bf2c29c252b0fc61a88c98fd Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 4 Mar 2026 16:32:05 +0100 Subject: [PATCH 018/103] Better LocationPinMarker --- .../components/LocationPinMarker.kt | 106 ++++++------------ 1 file changed, 33 insertions(+), 73 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt index a7b25554b5..e0550911f8 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt @@ -18,9 +18,8 @@ import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Matrix import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.Fill @@ -34,8 +33,6 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.avatarShape import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import kotlin.math.cos -import kotlin.math.sin /** * Variants of location pin markers. @@ -69,17 +66,13 @@ fun LocationPinMarker( Box( modifier = modifier.size(width = PIN_MARKER_WIDTH, height = PIN_MARKER_HEIGHT), ) { - // Draw the pin shape - Canvas( - modifier = Modifier.matchParentSize() - ) { + Canvas(modifier = Modifier.matchParentSize()) { drawPinShape( fillColor = colors.fill, strokeColor = colors.stroke, strokeWidth = 1.dp.toPx(), ) } - val avatarSize = PIN_MARKER_WIDTH - CONTENT_OFFSET * 2 val contentModifier = Modifier .align(Alignment.TopCenter) @@ -143,8 +136,8 @@ private data class LocationPinColors( avatarStoke = Color.Transparent, ) PinVariant.StaleLocation -> LocationPinColors( - fill = ElementTheme.colors.bgSubtlePrimary, - stroke = ElementTheme.colors.borderInteractiveSecondary, + fill = ElementTheme.colors.bgSubtleSecondary, + stroke = ElementTheme.colors.iconDisabled, dotColor = ElementTheme.colors.iconDisabled, avatarStoke = Color.Transparent, ) @@ -156,77 +149,44 @@ private data class LocationPinColors( /** * Draws a teardrop-shaped pin with smooth curves. * - * Based on SVG reference with dimensions 40x48 (ratio 1:1.2). - * Uses quadratic Bezier curves for smooth transitions from circle to tip. + * Based on SVG path with dimensions 40x48 (ratio 1:1.2). + * Scales automatically to fit the canvas size. */ private fun DrawScope.drawPinShape( fillColor: Color, strokeColor: Color, strokeWidth: Float, ) { - val width = size.width - val height = size.height - - val circleRadius = width / 2 - strokeWidth - val circleCenterX = width / 2 - val circleCenterY = width / 2 - - // The tip at the bottom - val tipX = width / 2 - val tipY = height - strokeWidth - - // Angle from the bottom of circle where it transitions to curves (in degrees) - val transitionAngleDeg = 65f - - val rightTransitionAngle = 90f - transitionAngleDeg - val leftTransitionAngle = 90f + transitionAngleDeg - - // Calculate transition points on the circle - val rightTransitionX = circleCenterX + circleRadius * cos(Math.toRadians(rightTransitionAngle.toDouble())).toFloat() - val rightTransitionY = circleCenterY + circleRadius * sin(Math.toRadians(rightTransitionAngle.toDouble())).toFloat() - val leftTransitionX = circleCenterX + circleRadius * cos(Math.toRadians(leftTransitionAngle.toDouble())).toFloat() - val leftTransitionY = circleCenterY + circleRadius * sin(Math.toRadians(leftTransitionAngle.toDouble())).toFloat() - - // Arc sweep: counter-clockwise over the top - val arcSweepAngle = -(360f - 2 * transitionAngleDeg) - - // For cubic Bezier: tangent direction at transition points - // Shorter tangent for smoother transition from circle - val tangentLength = (tipY - leftTransitionY) * 0.45f - - // Left side control points (from left transition to tip) - val leftTangentAngle = leftTransitionAngle - 90.0 - val leftC1X = leftTransitionX + tangentLength * cos(Math.toRadians(leftTangentAngle)).toFloat() - val leftC1Y = leftTransitionY + tangentLength * sin(Math.toRadians(leftTangentAngle)).toFloat() - // C2 control points - horizontal approach creates rounded tip - val tipOffset = 20f - val leftC2X = tipX - tipOffset - val leftC2Y = tipY - strokeWidth - // Right side control points (from tip to right transition) - val rightTangentAngle = rightTransitionAngle + 90.0 - val rightC1X = tipX + tipOffset - val rightC1Y = tipY - strokeWidth - val rightC2X = rightTransitionX + tangentLength * cos(Math.toRadians(rightTangentAngle)).toFloat() - val rightC2Y = rightTransitionY + tangentLength * sin(Math.toRadians(rightTangentAngle)).toFloat() + val svgWidth = 40f + val svgHeight = 48f + val inset = strokeWidth / 2 + val scaleX = (size.width - strokeWidth) / svgWidth + val scaleY = (size.height - strokeWidth) / svgHeight val path = Path().apply { - moveTo(rightTransitionX, rightTransitionY) - arcTo( - rect = Rect( - center = Offset(circleCenterX, circleCenterY), - radius = circleRadius, - ), - startAngleDegrees = rightTransitionAngle, - sweepAngleDegrees = arcSweepAngle, - forceMoveTo = false, - ) - - // Cubic Bezier from left transition point to tip - cubicTo(leftC1X, leftC1Y, leftC2X, leftC2Y, tipX, tipY) - // Cubic Bezier from tip back to right transition point - cubicTo(rightC1X, rightC1Y, rightC2X, rightC2Y, rightTransitionX, rightTransitionY) - + moveTo(20f, 48f) + cubicTo(19.4167f, 48f, 18.8333f, 47.8965f, 18.25f, 47.6895f) + cubicTo(17.6667f, 47.4825f, 17.1458f, 47.1721f, 16.6875f, 46.7581f) + cubicTo(13.9792f, 44.2743f, 11.5833f, 41.8525f, 9.5f, 39.4929f) + cubicTo(7.41667f, 37.1332f, 5.67708f, 34.8461f, 4.28125f, 32.6313f) + cubicTo(2.88542f, 30.4166f, 1.82292f, 28.2846f, 1.09375f, 26.2354f) + cubicTo(0.364583f, 24.1863f, 0f, 22.2303f, 0f, 20.3674f) + cubicTo(0f, 14.1578f, 2.01042f, 9.21087f, 6.03125f, 5.52652f) + cubicTo(10.0521f, 1.84217f, 14.7083f, 0f, 20f, 0f) + cubicTo(25.2917f, 0f, 29.9479f, 1.84217f, 33.9688f, 5.52652f) + cubicTo(37.9896f, 9.21087f, 40f, 14.1578f, 40f, 20.3674f) + cubicTo(40f, 22.2303f, 39.6354f, 24.1863f, 38.9062f, 26.2354f) + cubicTo(38.1771f, 28.2846f, 37.1146f, 30.4166f, 35.7188f, 32.6313f) + cubicTo(34.3229f, 34.8461f, 32.5833f, 37.1332f, 30.5f, 39.4929f) + cubicTo(28.4167f, 41.8525f, 26.0208f, 44.2743f, 23.3125f, 46.7581f) + cubicTo(22.8542f, 47.1721f, 22.3333f, 47.4825f, 21.75f, 47.6895f) + cubicTo(21.1667f, 47.8965f, 20.5833f, 48f, 20f, 48f) close() + + transform(Matrix().apply { + scale(scaleX, scaleY) + translate(inset / scaleX, inset / scaleY) + }) } drawPath(path = path, color = fillColor, style = Fill) From 34aad88023e2b58d7ddd0ba26699a097ede5a50f Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 4 Mar 2026 16:36:41 +0100 Subject: [PATCH 019/103] Remove PinIcon --- .../designsystem/components/PinIcon.kt | 48 ------------------- .../ui/components/AttachmentThumbnail.kt | 9 +--- 2 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt deleted file mode 100644 index 88287ef44b..0000000000 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * 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.libraries.designsystem.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.width -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.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.libraries.designsystem.R -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 - -@Composable -fun PinIcon( - modifier: Modifier = Modifier -) { - Box( - modifier = modifier - .background(ElementTheme.colors.bgSubtlePrimary) - ) { - Icon( - modifier = Modifier - .align(Alignment.Center) - .width(22.dp), - resourceId = R.drawable.pin, - contentDescription = null, - tint = Color.Unspecified, - ) - } -} - -@PreviewsDayNight -@Composable -internal fun PinIconPreview() = ElementPreview { - PinIcon() -} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt index 8ffdc1b003..9b55c85524 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt @@ -25,7 +25,6 @@ import androidx.compose.ui.layout.ContentScale 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.libraries.designsystem.components.PinIcon import io.element.android.libraries.designsystem.components.blurhash.BlurHashAsyncImage import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -99,16 +98,10 @@ fun AttachmentThumbnail( ) } AttachmentThumbnailType.Location -> { - PinIcon( - modifier = Modifier.fillMaxSize() - ) - /* - // For coherency across the app, we should us this instead. Waiting for design decision. Icon( - resourceId = R.drawable.ic_september_location, + imageVector = CompoundIcons.LocationPin(), contentDescription = info.textContent, ) - */ } AttachmentThumbnailType.Poll -> { Icon( From 3cce8caec41830cbf5cda44ed107ae9ddac56b38 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 5 Mar 2026 14:50:55 +0100 Subject: [PATCH 020/103] Introduce LocationPinMarkers composable --- .../features/location/api/StaticMapView.kt | 7 +- .../impl/common/ui/LocationPinMarkers.kt | 188 ++++++++++++++++++ .../location/impl/common/ui/MapProjected.kt | 37 ---- .../impl/common/ui/RememberMarkerBitmap.kt | 87 ++++++++ .../location/impl/share/ShareLocationView.kt | 4 +- .../location/impl/show/ShowLocationView.kt | 76 +++++-- .../{LocationPinMarker.kt => LocationPin.kt} | 14 +- 7 files changed, 343 insertions(+), 70 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/{LocationPinMarker.kt => LocationPin.kt} (96%) diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt index 7d7752ba62..0657bae634 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt @@ -19,7 +19,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity @@ -32,12 +31,10 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.api.internal.StaticMapPlaceholder import io.element.android.features.location.api.internal.StaticMapUrlBuilder import io.element.android.features.location.api.internal.centerBottomEdge -import io.element.android.libraries.designsystem.components.LocationPinMarker +import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant 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.designsystem.utils.CommonDrawables /** * Shows a static map image downloaded via a third party service's static maps API. @@ -98,7 +95,7 @@ fun StaticMapView( // We apply ContentScale.Fit to scale the image to fill the AsyncImage should this be the case. contentScale = ContentScale.Fit, ) - LocationPinMarker(variant = pinVariant, modifier = Modifier.centerBottomEdge(this)) + LocationPin(variant = pinVariant, modifier = Modifier.centerBottomEdge(this)) } else { StaticMapPlaceholder( showProgress = collectedState.value.isLoading(), diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt new file mode 100644 index 0000000000..ad3a4c48e1 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.location.api.Location +import io.element.android.libraries.designsystem.components.LocationPin +import io.element.android.libraries.designsystem.components.PinVariant +import kotlinx.serialization.json.JsonPrimitive +import org.maplibre.compose.expressions.dsl.and +import org.maplibre.compose.expressions.dsl.asNumber +import org.maplibre.compose.expressions.dsl.asString +import org.maplibre.compose.expressions.dsl.const +import org.maplibre.compose.expressions.dsl.eq +import org.maplibre.compose.expressions.dsl.feature +import org.maplibre.compose.expressions.dsl.image +import org.maplibre.compose.expressions.dsl.not +import org.maplibre.compose.expressions.dsl.step +import org.maplibre.compose.expressions.value.SymbolAnchor +import org.maplibre.compose.expressions.value.SymbolPlacement +import org.maplibre.compose.layers.CircleLayer +import org.maplibre.compose.layers.SymbolLayer +import org.maplibre.compose.sources.GeoJsonData +import org.maplibre.compose.sources.GeoJsonOptions +import org.maplibre.compose.sources.GeoJsonSource +import org.maplibre.compose.sources.rememberGeoJsonSource +import org.maplibre.compose.util.ClickResult +import org.maplibre.spatialk.geojson.Feature +import org.maplibre.spatialk.geojson.FeatureCollection +import org.maplibre.spatialk.geojson.Point +import org.maplibre.spatialk.geojson.Position +import org.maplibre.spatialk.geojson.toJson + +/** + * Data class representing a marker on the map. + * + * @param id Unique identifier for the marker + * @param location The geographic location of the marker + * @param variant The visual variant of the pin (user location, pinned, stale) + */ +data class LocationMarkerData( + val id: String, + val location: Location, + val variant: PinVariant, +) + +/** + * A composable that renders location markers on a MapLibre map with clustering support. + * + * Uses GeoJSON source with clustering enabled to group nearby markers. + * Individual markers are rendered using [LocationPin] composable converted to bitmaps. + * Clusters are rendered as circles with point counts. + * + * Must be used within a MaplibreMap content block. + * + * @param markers List of markers to display on the map + * @param clusterRadius Radius of each cluster when clustering points (default 50) + * @param clusterMaxZoom Maximum zoom level at which to cluster points (default 14) + * @param onMarkerClick Callback when a marker is clicked + * @param onClusterClick Callback when a cluster is clicked, provides cluster center position + */ +@Composable +fun LocationPinMarkers( + markers: List, + onMarkerClick: ((LocationMarkerData) -> Unit)? = null, + onClusterClick: ((Position) -> Unit)? = null, +) { + if (markers.isEmpty()) return + val clusterColor = ElementTheme.colors.bgAccentRest + val clusterStrokeColor = ElementTheme.colors.iconOnSolidPrimary + val clusterTextColor = ElementTheme.colors.textOnSolidPrimary + val clusterTextStyle = ElementTheme.typography.fontBodyMdMedium + + // Convert markers to GeoJSON + val geoJsonString = remember(markers) { + val features = markers.map { marker -> + Feature( + id = JsonPrimitive(marker.id), + geometry = Point(Position(marker.location.lon, marker.location.lat)), + properties = mapOf( + "id" to JsonPrimitive(marker.id), + ) + ) + } + FeatureCollection(features).toJson() + } + + // Create GeoJSON source with clustering + val markersSource = rememberGeoJsonSource( + data = GeoJsonData.JsonString(geoJsonString), + options = GeoJsonOptions( + cluster = true, + clusterMinPoints = 3, + clusterRadius = 30 + ), + ) + + // Cluster circle layer + CircleLayer( + id = "cluster-circles", + source = markersSource, + filter = feature.has("point_count"), + color = const(clusterColor), + radius = const(24.dp), + strokeWidth = const(1.dp), + strokeColor = const(clusterStrokeColor), + onClick = { features -> + features.firstOrNull()?.let { feat -> + val point = feat.geometry as? Point + if (point != null && onClusterClick != null) { + onClusterClick(point.coordinates) + ClickResult.Consume + } else { + ClickResult.Pass + } + } ?: ClickResult.Pass + }, + ) + + // Cluster count text layer + SymbolLayer( + id = "cluster-count", + source = markersSource, + filter = feature.has("point_count"), + textField = feature["point_count_abbreviated"].asString(), + textColor = const(clusterTextColor), + textSize = const(clusterTextStyle.fontSize), + textFont = const(listOfNotNull(clusterTextStyle.fontFamily?.toString())), + textLetterSpacing = const(clusterTextStyle.letterSpacing), + ) + + // Individual marker layers - one per marker for unique avatars + markers.forEach { marker -> + LocationPinMarkerLayer( + marker = marker, + source = markersSource, + onMarkerClick = onMarkerClick, + ) + } +} + +@Composable +private fun LocationPinMarkerLayer( + marker: LocationMarkerData, + source: GeoJsonSource, + onMarkerClick: ((LocationMarkerData) -> Unit)?, +) { + val imageBitmap = rememberLocationPinImage(marker.variant) + SymbolLayer( + id = "pin-marker-${marker.id}", + source = source, + filter = !feature.has("point_count") and (feature["id"].asString() eq const(marker.id)), + iconImage = image(imageBitmap), + iconAnchor = const(SymbolAnchor.Bottom), + iconAllowOverlap = const(true), + onClick = { features -> + if (features.isNotEmpty() && onMarkerClick != null) { + onMarkerClick(marker) + ClickResult.Consume + } else { + ClickResult.Pass + } + }, + ) +} + +/** + * Renders a LocationPin composable to an ImageBitmap for use in SymbolLayer. + */ +@Composable +private fun rememberLocationPinImage(variant: PinVariant): ImageBitmap { + val bitmap = rememberMarkerBitmap(variant) { + LocationPin(variant = variant) + } + return bitmap.asImageBitmap() +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt deleted file mode 100644 index 503e6ea3d7..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapProjected.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2026 Element Creations 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.location.impl.common.ui - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.graphicsLayer -import org.maplibre.compose.camera.CameraState -import org.maplibre.spatialk.geojson.Position - -@Composable -fun MapProjected( - target: Position, - cameraState: CameraState, - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - Box( - modifier = modifier - .graphicsLayer { - cameraState.position - val offset = cameraState.projection?.screenLocationFromPosition(target) - if (offset != null) { - translationX = offset.x.toPx() - size.width / 2 - translationY = offset.y.toPx() - size.height - } - } - ) { - content() - } -} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt new file mode 100644 index 0000000000..6c083e2a45 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.os.Build +import android.view.View +import android.view.ViewGroup +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionContext +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCompositionContext +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.LocalView +import androidx.core.graphics.createBitmap + +/** + * Renders a composable [content] to an Android [Bitmap]. + * Useful for MapLibre SymbolLayer rendering. + * + * Uses a temporary ComposeView to render off-screen without + * adding to the visible composition tree. + * + * Note: This function provides a software-only ImageLoader to avoid + * "Software rendering doesn't support hardware bitmaps" errors when + * rendering Coil images to a Canvas. + * + * @param keys to trigger recomposition. + * @return The rendered Android [Bitmap]. + */ +@Composable +fun rememberMarkerBitmap( + vararg keys: Any, + content: @Composable () -> Unit, +): Bitmap { + val parent = LocalView.current as ViewGroup + val compositionContext = rememberCompositionContext() + return remember(parent, compositionContext, *keys) { + renderComposableToBitmap(parent, compositionContext, content) + } +} + +private fun renderComposableToBitmap( + parent: ViewGroup, + compositionContext: CompositionContext, + content: @Composable () -> Unit, +): Bitmap { + val composeView = ComposeView(parent.context).apply { + setParentCompositionContext(compositionContext) + setContent(content) + } + // Temporarily add to parent for measurement + parent.addView( + composeView, + ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + ) + // Measure + composeView.measure( + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) + ) + + val width = composeView.measuredWidth + val height = composeView.measuredHeight + + // Layout + composeView.layout(0, 0, width, height) + + // Draw to bitmap + val bitmap = createBitmap(width, height) + val canvas = Canvas(bitmap) + composeView.draw(canvas) + + // Cleanup + parent.removeView(composeView) + + return bitmap +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 02b209ae43..a0705221c0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -40,7 +40,7 @@ import io.element.android.features.location.impl.common.PermissionRationaleDialo import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck -import io.element.android.libraries.designsystem.components.LocationPinMarker +import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton @@ -160,7 +160,7 @@ fun ShareLocationView( } else { PinVariant.PinnedLocation } - LocationPinMarker( + LocationPin( variant = variant, modifier = Modifier.centerBottomEdge(this), ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 69ac04e0c5..d1a3537d7a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -8,8 +8,6 @@ package io.element.android.features.location.impl.show -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue @@ -17,25 +15,23 @@ import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -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.compound.tokens.generated.TypographyTokens +import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton +import io.element.android.features.location.impl.common.ui.LocationMarkerData +import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold -import io.element.android.features.location.impl.common.ui.MapProjected import io.element.android.features.location.impl.common.ui.UserLocationPuck -import io.element.android.libraries.designsystem.components.LocationPinMarker import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -44,7 +40,6 @@ 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.designsystem.theme.components.IconButton -import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.ui.strings.CommonStrings @@ -56,6 +51,10 @@ import org.maplibre.compose.location.rememberDefaultLocationProvider import org.maplibre.compose.location.rememberNullLocationProvider import org.maplibre.compose.location.rememberUserLocationState import org.maplibre.spatialk.geojson.Position +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt +import kotlin.random.Random import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @@ -138,8 +137,6 @@ fun ShowLocationView( locationState = userLocationState, trackUserLocation = state.isTrackMyLocation ) - }, - overlayContent = { when (val mode = state.mode) { is ShowLocationMode.Static -> { val pinVariant = if (mode.assetType == AssetType.PIN) { @@ -147,23 +144,64 @@ fun ShowLocationView( } else { PinVariant.UserLocation( avatarData = AvatarData(mode.senderId.value, mode.senderName, mode.senderAvatarUrl, AvatarSize.UserListItem), - isLive = false + isLive = true ) } - val position = Position( - latitude = mode.location.lat, - longitude = mode.location.lon - ) - MapProjected(target = position, cameraState = cameraState) { - LocationPinMarker(variant = pinVariant) + // Generate test markers around the original location + val testMarkers = remember { + buildList { + // Add the original marker + add( + LocationMarkerData( + id = "original", + location = mode.location, + variant = pinVariant + ) + ) + // Generate 10 random points within 50 meters + val radiusInMeters = 50.0 + val metersPerDegreeLat = 111_320.0 + val metersPerDegreeLon = 111_320.0 * cos(Math.toRadians(mode.location.lat)) + val variants = listOf( + PinVariant.StaleLocation, + PinVariant.UserLocation(AvatarData("@alice", "Alice", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@bob", "Bob", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@cassy", "Cassy", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@daisy", "Daisy", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@en", "G", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@f", "H", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@g", "I", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@h", "J", null, AvatarSize.TimelineSender), isLive = true), + PinVariant.UserLocation(AvatarData("@i", "K", null, AvatarSize.TimelineSender), isLive = true), + ) + repeat(10) { index -> + // Random point in a circle using sqrt for uniform distribution + val angle = Random.nextDouble() * 2 * Math.PI + val distance = sqrt(Random.nextDouble()) * radiusInMeters + val latOffset = (distance * cos(angle)) / metersPerDegreeLat + val lonOffset = (distance * sin(angle)) / metersPerDegreeLon + add( + LocationMarkerData( + id = "test_$index", + location = Location( + lat = mode.location.lat + latOffset, + lon = mode.location.lon + lonOffset + ), + variant = variants[index % (variants.size-1)] + ) + ) + } + } } + LocationPinMarkers(testMarkers) } ShowLocationMode.Live -> { // TODO: Show pins for all active live location sharers } } - + }, + overlayContent = { LocationFloatingActionButton( isMapCenteredOnUser = state.isTrackMyLocation, onClick = { state.eventSink(ShowLocationEvents.TrackMyLocation(true)) }, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt similarity index 96% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index e0550911f8..60bccc1228 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPinMarker.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -53,12 +53,12 @@ private val DOT_RADIUS = 6.dp private val CONTENT_OFFSET = 5.dp /** - * A location pin marker composable that supports multiple variants. + * A location pin composable that supports multiple variants. * * Based on Figma design: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=4665-2890&m=dev */ @Composable -fun LocationPinMarker( +fun LocationPin( variant: PinVariant, modifier: Modifier = Modifier, ) { @@ -195,7 +195,7 @@ private fun DrawScope.drawPinShape( @PreviewsDayNight @Composable -internal fun LocationPinMarkerPreview() = ElementPreview { +internal fun LocationPinPreview() = ElementPreview { val sampleAvatarData = AvatarData( id = "@alice:matrix.org", name = "Alice", @@ -208,18 +208,18 @@ internal fun LocationPinMarkerPreview() = ElementPreview { horizontalAlignment = Alignment.CenterHorizontally, ) { Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { - LocationPinMarker( + LocationPin( variant = PinVariant.UserLocation(avatarData = sampleAvatarData, isLive = false), ) - LocationPinMarker( + LocationPin( variant = PinVariant.UserLocation(avatarData = sampleAvatarData, isLive = true), ) } Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { - LocationPinMarker( + LocationPin( variant = PinVariant.PinnedLocation, ) - LocationPinMarker( + LocationPin( variant = PinVariant.StaleLocation, ) } From 4704a6fc2a758e821a587efb6efd9de6e60c5b88 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 5 Mar 2026 18:03:29 +0100 Subject: [PATCH 021/103] LocationPin : disable hardware rendering if needed --- .../location/impl/common/ui/LocationPinMarkers.kt | 6 +++++- .../designsystem/components/LocationPin.kt | 14 ++++++++++---- .../components/avatar/internal/ImageAvatar.kt | 10 +++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt index ad3a4c48e1..6fed056a28 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt @@ -182,7 +182,11 @@ private fun LocationPinMarkerLayer( @Composable private fun rememberLocationPinImage(variant: PinVariant): ImageBitmap { val bitmap = rememberMarkerBitmap(variant) { - LocationPin(variant = variant) + LocationPin( + variant = variant, + // Disable as it doesn't work with the rememberMarkerBitmap method + allowHardwareBitmapRendering = false + ) } return bitmap.asImageBitmap() } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index 60bccc1228..60f83ffea1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -25,12 +25,13 @@ import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.unit.dp +import coil3.request.allowHardware import io.element.android.compound.theme.ElementTheme -import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.avatarShape +import io.element.android.libraries.designsystem.components.avatar.internal.ImageAvatar import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -61,6 +62,7 @@ private val CONTENT_OFFSET = 5.dp fun LocationPin( variant: PinVariant, modifier: Modifier = Modifier, + allowHardwareBitmapRendering: Boolean = true, ) { val colors = LocationPinColors.fromVariant(variant) Box( @@ -80,12 +82,16 @@ fun LocationPin( when (variant) { is PinVariant.UserLocation -> { - Avatar( + val avatarShape = AvatarType.User.avatarShape() + ImageAvatar( avatarData = variant.avatarData, forcedAvatarSize = avatarSize, - avatarType = AvatarType.User, + avatarShape = avatarShape, modifier = contentModifier - .border(width = 1.dp, color = colors.avatarStoke, shape = AvatarType.User.avatarShape()), + .border(width = 1.dp, color = colors.avatarStoke, shape = avatarShape), + configureRequest = { builder -> + builder.allowHardware(allowHardwareBitmapRendering) + } ) } PinVariant.PinnedLocation, PinVariant.StaleLocation -> { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt index da57fbcbe1..10136bb5c1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt @@ -17,10 +17,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.Dp import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent +import coil3.request.ImageRequest import io.element.android.libraries.designsystem.components.avatar.AvatarData import timber.log.Timber @@ -31,10 +33,16 @@ internal fun ImageAvatar( forcedAvatarSize: Dp?, modifier: Modifier = Modifier, contentDescription: String? = null, + configureRequest: (ImageRequest.Builder) -> ImageRequest.Builder = { it }, ) { val size = forcedAvatarSize ?: avatarData.size.dp + val request = ImageRequest.Builder(LocalContext.current) + .data(avatarData) + .let(configureRequest) + .build() + SubcomposeAsyncImage( - model = avatarData, + model = request, contentDescription = contentDescription, contentScale = ContentScale.Crop, modifier = modifier From d53db78856c5e56b881534926dfbf0c2cd1b4327 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 5 Mar 2026 21:50:56 +0100 Subject: [PATCH 022/103] Use android.graphic.canvas to create proper bitmap --- features/location/impl/build.gradle.kts | 1 + .../impl/common/ui/LocationPinMarkers.kt | 60 +-- .../impl/common/ui/RememberMarkerBitmap.kt | 87 ---- .../designsystem/components/LocationPin.kt | 438 ++++++++++++------ 4 files changed, 320 insertions(+), 266 deletions(-) delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index 558cd86b25..94f1ea07dd 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { api(projects.features.location.api) implementation(projects.features.messages.api) implementation(libs.maplibre.compose) + implementation(libs.coil) implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) implementation(projects.libraries.di) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt index 6fed056a28..7fce6ab281 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt @@ -9,27 +9,20 @@ package io.element.android.features.location.impl.common.ui import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.api.Location -import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant +import io.element.android.libraries.designsystem.components.rememberLocationPinBitmap import kotlinx.serialization.json.JsonPrimitive import org.maplibre.compose.expressions.dsl.and -import org.maplibre.compose.expressions.dsl.asNumber import org.maplibre.compose.expressions.dsl.asString import org.maplibre.compose.expressions.dsl.const import org.maplibre.compose.expressions.dsl.eq import org.maplibre.compose.expressions.dsl.feature import org.maplibre.compose.expressions.dsl.image import org.maplibre.compose.expressions.dsl.not -import org.maplibre.compose.expressions.dsl.step import org.maplibre.compose.expressions.value.SymbolAnchor -import org.maplibre.compose.expressions.value.SymbolPlacement import org.maplibre.compose.layers.CircleLayer import org.maplibre.compose.layers.SymbolLayer import org.maplibre.compose.sources.GeoJsonData @@ -60,14 +53,12 @@ data class LocationMarkerData( * A composable that renders location markers on a MapLibre map with clustering support. * * Uses GeoJSON source with clustering enabled to group nearby markers. - * Individual markers are rendered using [LocationPin] composable converted to bitmaps. + * Individual markers are rendered using Canvas-based pin rendering with Coil for avatar loading. * Clusters are rendered as circles with point counts. * * Must be used within a MaplibreMap content block. * * @param markers List of markers to display on the map - * @param clusterRadius Radius of each cluster when clustering points (default 50) - * @param clusterMaxZoom Maximum zoom level at which to cluster points (default 14) * @param onMarkerClick Callback when a marker is clicked * @param onClusterClick Callback when a cluster is clicked, provides cluster center position */ @@ -157,36 +148,23 @@ private fun LocationPinMarkerLayer( source: GeoJsonSource, onMarkerClick: ((LocationMarkerData) -> Unit)?, ) { - val imageBitmap = rememberLocationPinImage(marker.variant) - SymbolLayer( - id = "pin-marker-${marker.id}", - source = source, - filter = !feature.has("point_count") and (feature["id"].asString() eq const(marker.id)), - iconImage = image(imageBitmap), - iconAnchor = const(SymbolAnchor.Bottom), - iconAllowOverlap = const(true), - onClick = { features -> - if (features.isNotEmpty() && onMarkerClick != null) { - onMarkerClick(marker) - ClickResult.Consume - } else { - ClickResult.Pass - } - }, - ) -} - -/** - * Renders a LocationPin composable to an ImageBitmap for use in SymbolLayer. - */ -@Composable -private fun rememberLocationPinImage(variant: PinVariant): ImageBitmap { - val bitmap = rememberMarkerBitmap(variant) { - LocationPin( - variant = variant, - // Disable as it doesn't work with the rememberMarkerBitmap method - allowHardwareBitmapRendering = false + val imageBitmap = rememberLocationPinBitmap(marker.variant) + if (imageBitmap != null) { + SymbolLayer( + id = "pin-marker-${marker.id}", + source = source, + filter = !feature.has("point_count") and (feature["id"].asString() eq const(marker.id)), + iconImage = image(imageBitmap), + iconAnchor = const(SymbolAnchor.Bottom), + iconAllowOverlap = const(true), + onClick = { features -> + if (features.isNotEmpty() && onMarkerClick != null) { + onMarkerClick(marker) + ClickResult.Consume + } else { + ClickResult.Pass + } + }, ) } - return bitmap.asImageBitmap() } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt deleted file mode 100644 index 6c083e2a45..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/RememberMarkerBitmap.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2026 Element Creations 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.location.impl.common.ui - -import android.graphics.Bitmap -import android.graphics.Canvas -import android.os.Build -import android.view.View -import android.view.ViewGroup -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionContext -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCompositionContext -import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.LocalView -import androidx.core.graphics.createBitmap - -/** - * Renders a composable [content] to an Android [Bitmap]. - * Useful for MapLibre SymbolLayer rendering. - * - * Uses a temporary ComposeView to render off-screen without - * adding to the visible composition tree. - * - * Note: This function provides a software-only ImageLoader to avoid - * "Software rendering doesn't support hardware bitmaps" errors when - * rendering Coil images to a Canvas. - * - * @param keys to trigger recomposition. - * @return The rendered Android [Bitmap]. - */ -@Composable -fun rememberMarkerBitmap( - vararg keys: Any, - content: @Composable () -> Unit, -): Bitmap { - val parent = LocalView.current as ViewGroup - val compositionContext = rememberCompositionContext() - return remember(parent, compositionContext, *keys) { - renderComposableToBitmap(parent, compositionContext, content) - } -} - -private fun renderComposableToBitmap( - parent: ViewGroup, - compositionContext: CompositionContext, - content: @Composable () -> Unit, -): Bitmap { - val composeView = ComposeView(parent.context).apply { - setParentCompositionContext(compositionContext) - setContent(content) - } - // Temporarily add to parent for measurement - parent.addView( - composeView, - ViewGroup.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) - ) - // Measure - composeView.measure( - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) - ) - - val width = composeView.measuredWidth - val height = composeView.measuredHeight - - // Layout - composeView.layout(0, 0, width, height) - - // Draw to bitmap - val bitmap = createBitmap(width, height) - val canvas = Canvas(bitmap) - composeView.draw(canvas) - - // Cleanup - parent.removeView(composeView) - - return bitmap -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index 60f83ffea1..75129f6795 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -7,31 +7,42 @@ package io.element.android.libraries.designsystem.components +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Matrix +import android.graphics.Paint +import android.graphics.Path +import android.graphics.Rect +import android.graphics.RectF import androidx.compose.foundation.Canvas -import androidx.compose.foundation.border 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.offset import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.runtime.produceState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Matrix -import androidx.compose.ui.graphics.Path -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.drawscope.Fill -import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp +import androidx.core.graphics.createBitmap +import androidx.core.graphics.withSave +import coil3.Image +import coil3.SingletonImageLoader +import coil3.request.ImageRequest import coil3.request.allowHardware +import coil3.toBitmap import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.avatar.AvatarType -import io.element.android.libraries.designsystem.components.avatar.avatarShape -import io.element.android.libraries.designsystem.components.avatar.internal.ImageAvatar import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -48,11 +59,6 @@ sealed interface PinVariant { data object StaleLocation : PinVariant } -private val PIN_MARKER_WIDTH = 42.dp -private val PIN_MARKER_HEIGHT = (PIN_MARKER_WIDTH * 1.2f) -private val DOT_RADIUS = 6.dp -private val CONTENT_OFFSET = 5.dp - /** * A location pin composable that supports multiple variants. * @@ -62,141 +68,297 @@ private val CONTENT_OFFSET = 5.dp fun LocationPin( variant: PinVariant, modifier: Modifier = Modifier, - allowHardwareBitmapRendering: Boolean = true, ) { - val colors = LocationPinColors.fromVariant(variant) - Box( - modifier = modifier.size(width = PIN_MARKER_WIDTH, height = PIN_MARKER_HEIGHT), - ) { - Canvas(modifier = Modifier.matchParentSize()) { - drawPinShape( - fillColor = colors.fill, - strokeColor = colors.stroke, - strokeWidth = 1.dp.toPx(), - ) - } - val avatarSize = PIN_MARKER_WIDTH - CONTENT_OFFSET * 2 - val contentModifier = Modifier - .align(Alignment.TopCenter) - .offset(y = CONTENT_OFFSET) - - when (variant) { - is PinVariant.UserLocation -> { - val avatarShape = AvatarType.User.avatarShape() - ImageAvatar( - avatarData = variant.avatarData, - forcedAvatarSize = avatarSize, - avatarShape = avatarShape, - modifier = contentModifier - .border(width = 1.dp, color = colors.avatarStoke, shape = avatarShape), - configureRequest = { builder -> - builder.allowHardware(allowHardwareBitmapRendering) - } - ) - } - PinVariant.PinnedLocation, PinVariant.StaleLocation -> { - Canvas( - modifier = contentModifier.size(avatarSize) - ) { - drawCircle( - color = colors.dotColor, - radius = DOT_RADIUS.toPx(), - center = center, - ) - } - } - } - } -} - -private data class LocationPinColors( - val fill: Color, - val stroke: Color, - val dotColor: Color, - val avatarStoke: Color, -) { - companion object { - @Composable - fun fromVariant(variant: PinVariant): LocationPinColors { - return when (variant) { - is PinVariant.UserLocation -> - if (variant.isLive) { - LocationPinColors( - fill = ElementTheme.colors.iconAccentPrimary, - stroke = ElementTheme.colors.bgCanvasDefault, - dotColor = Color.Transparent, - avatarStoke = ElementTheme.colors.bgCanvasDefault, - ) - } else { - LocationPinColors( - fill = ElementTheme.colors.bgCanvasDefault, - stroke = ElementTheme.colors.iconQuaternaryAlpha, - dotColor = Color.Transparent, - avatarStoke = ElementTheme.colors.iconQuaternaryAlpha, - ) - } - PinVariant.PinnedLocation -> LocationPinColors( - fill = ElementTheme.colors.bgCanvasDefault, - stroke = ElementTheme.colors.iconSecondaryAlpha, - dotColor = ElementTheme.colors.iconPrimary, - avatarStoke = Color.Transparent, - ) - PinVariant.StaleLocation -> LocationPinColors( - fill = ElementTheme.colors.bgSubtleSecondary, - stroke = ElementTheme.colors.iconDisabled, - dotColor = ElementTheme.colors.iconDisabled, - avatarStoke = Color.Transparent, - ) - } + val image = rememberLocationPinBitmap(variant) + Canvas(modifier = modifier.size(PIN_WIDTH, PIN_HEIGHT)) { + if (image != null) { + drawImage(image) } } } /** - * Draws a teardrop-shaped pin with smooth curves. - * - * Based on SVG path with dimensions 40x48 (ratio 1:1.2). - * Scales automatically to fit the canvas size. + * Renders a location pin to an [ImageBitmap] using Canvas operations. + * @param variant The pin variant to render + * @return The rendered [ImageBitmap], or null if still loading */ -private fun DrawScope.drawPinShape( - fillColor: Color, - strokeColor: Color, - strokeWidth: Float, +@Composable +fun rememberLocationPinBitmap(variant: PinVariant): ImageBitmap? { + val context = LocalContext.current + val density = LocalDensity.current + val colors = pinColors(variant) + return produceState(initialValue = null, variant, colors) { + val renderer = LocationPinRenderer(context, density) + val bitmap = renderer.renderPin(variant, colors) + value = bitmap.asImageBitmap() + }.value +} + +private val PIN_WIDTH = 42.dp +private val PIN_HEIGHT = PIN_WIDTH * 1.2f +private val AVATAR_SIZE = PIN_WIDTH - 10.dp +private val CONTENT_OFFSET = 5.dp +private val DOT_RADIUS = 6.dp +private val STROKE_WIDTH = 1.dp + +@Composable +private fun pinColors(variant: PinVariant): PinColors { + return when (variant) { + is PinVariant.UserLocation -> { + val avatarColors = AvatarColorsProvider.provide(variant.avatarData.id) + if (variant.isLive) { + PinColors( + fill = ElementTheme.colors.iconAccentPrimary, + stroke = Color.Transparent, + dot = Color.Transparent, + avatarStroke = ElementTheme.colors.bgCanvasDefault, + avatarBackground = avatarColors.background, + avatarForeground = avatarColors.foreground, + ) + } else { + PinColors( + fill = ElementTheme.colors.bgCanvasDefault, + stroke = ElementTheme.colors.iconQuaternaryAlpha, + dot = Color.Transparent, + avatarStroke = ElementTheme.colors.iconQuaternaryAlpha, + avatarBackground = avatarColors.background, + avatarForeground = avatarColors.foreground, + ) + } + } + PinVariant.PinnedLocation -> PinColors( + fill = ElementTheme.colors.bgCanvasDefault, + stroke = ElementTheme.colors.iconSecondaryAlpha, + avatarStroke = Color.Transparent, + avatarBackground = Color.Transparent, + avatarForeground = Color.Transparent, + dot = ElementTheme.colors.iconPrimary, + ) + PinVariant.StaleLocation -> PinColors( + fill = ElementTheme.colors.bgSubtleSecondary, + stroke = ElementTheme.colors.iconDisabled, + avatarStroke = Color.Transparent, + avatarBackground = Color.Transparent, + avatarForeground = Color.Transparent, + dot = ElementTheme.colors.iconDisabled, + ) + } +} + +/** + * Color configuration for rendering a location pin. + */ +data class PinColors( + val fill: Color, + val stroke: Color, + val dot: Color, + val avatarStroke: Color, + val avatarBackground: Color, + val avatarForeground: Color, +) + +/** + * Renders location pins to bitmaps using Canvas operations. + * Uses Coil for avatar loading with proper memory management. + */ +class LocationPinRenderer( + private val context: Context, + private val density: Density, ) { - val svgWidth = 40f - val svgHeight = 48f - val inset = strokeWidth / 2 - val scaleX = (size.width - strokeWidth) / svgWidth - val scaleY = (size.height - strokeWidth) / svgHeight + // Dimensions in pixels + private val pinWidthPx = with(density) { PIN_WIDTH.toPx() } + private val pinHeightPx = with(density) { PIN_HEIGHT.toPx() } + private val avatarSizePx = with(density) { AVATAR_SIZE.toPx() } + private val avatarOffsetPx = with(density) { CONTENT_OFFSET.toPx() } + private val dotRadiusPx = with(density) { DOT_RADIUS.toPx() } + private val strokeWidthPx = with(density) { STROKE_WIDTH.toPx() } - val path = Path().apply { - moveTo(20f, 48f) - cubicTo(19.4167f, 48f, 18.8333f, 47.8965f, 18.25f, 47.6895f) - cubicTo(17.6667f, 47.4825f, 17.1458f, 47.1721f, 16.6875f, 46.7581f) - cubicTo(13.9792f, 44.2743f, 11.5833f, 41.8525f, 9.5f, 39.4929f) - cubicTo(7.41667f, 37.1332f, 5.67708f, 34.8461f, 4.28125f, 32.6313f) - cubicTo(2.88542f, 30.4166f, 1.82292f, 28.2846f, 1.09375f, 26.2354f) - cubicTo(0.364583f, 24.1863f, 0f, 22.2303f, 0f, 20.3674f) - cubicTo(0f, 14.1578f, 2.01042f, 9.21087f, 6.03125f, 5.52652f) - cubicTo(10.0521f, 1.84217f, 14.7083f, 0f, 20f, 0f) - cubicTo(25.2917f, 0f, 29.9479f, 1.84217f, 33.9688f, 5.52652f) - cubicTo(37.9896f, 9.21087f, 40f, 14.1578f, 40f, 20.3674f) - cubicTo(40f, 22.2303f, 39.6354f, 24.1863f, 38.9062f, 26.2354f) - cubicTo(38.1771f, 28.2846f, 37.1146f, 30.4166f, 35.7188f, 32.6313f) - cubicTo(34.3229f, 34.8461f, 32.5833f, 37.1332f, 30.5f, 39.4929f) - cubicTo(28.4167f, 41.8525f, 26.0208f, 44.2743f, 23.3125f, 46.7581f) - cubicTo(22.8542f, 47.1721f, 22.3333f, 47.4825f, 21.75f, 47.6895f) - cubicTo(21.1667f, 47.8965f, 20.5833f, 48f, 20f, 48f) - close() + /** + * Renders a pin variant to bitmap. Suspending for async avatar loading. + */ + suspend fun renderPin( + variant: PinVariant, + colors: PinColors, + ): Bitmap { + val bitmap = createBitmap(pinWidthPx.toInt(), pinHeightPx.toInt()) + val canvas = Canvas(bitmap) + // Draw pin shape (fill + stroke) + canvas.drawPinShape(colors.fill, colors.stroke) + when (variant) { + is PinVariant.UserLocation -> { + val avatarImage = loadAvatarImage(variant.avatarData) + canvas.drawAvatar( + avatarImage = avatarImage, + avatarData = variant.avatarData, + borderColor = colors.avatarStroke, + backgroundColor = colors.avatarBackground, + foregroundColor = colors.avatarForeground + ) + } + PinVariant.PinnedLocation, + PinVariant.StaleLocation -> canvas.drawDot(colors.dot) + } + return bitmap + } - transform(Matrix().apply { - scale(scaleX, scaleY) - translate(inset / scaleX, inset / scaleY) + private fun Canvas.drawPinShape(fillColor: Color, strokeColor: Color) { + val path = createPinPath() + // Fill + drawPath(path, Paint().apply { + color = fillColor.toArgb() + style = Paint.Style.FILL + isAntiAlias = true + }) + // Stroke + drawPath(path, Paint().apply { + color = strokeColor.toArgb() + style = Paint.Style.STROKE + strokeWidth = strokeWidthPx + isAntiAlias = true }) } - drawPath(path = path, color = fillColor, style = Fill) - drawPath(path = path, color = strokeColor, style = Stroke(width = strokeWidth)) + /** + * Creates the teardrop-shaped pin path. + * Based on SVG path with dimensions 40x48 (ratio 1:1.2). + * Scales automatically to fit the actual size. + */ + private fun createPinPath(): Path { + val svgWidth = 40f + val svgHeight = 48f + val inset = strokeWidthPx / 2 + val scaleX = (pinWidthPx - strokeWidthPx) / svgWidth + val scaleY = (pinHeightPx - strokeWidthPx) / svgHeight + + val path = Path().apply { + moveTo(20f, 48f) + cubicTo(19.4167f, 48f, 18.8333f, 47.8965f, 18.25f, 47.6895f) + cubicTo(17.6667f, 47.4825f, 17.1458f, 47.1721f, 16.6875f, 46.7581f) + cubicTo(13.9792f, 44.2743f, 11.5833f, 41.8525f, 9.5f, 39.4929f) + cubicTo(7.41667f, 37.1332f, 5.67708f, 34.8461f, 4.28125f, 32.6313f) + cubicTo(2.88542f, 30.4166f, 1.82292f, 28.2846f, 1.09375f, 26.2354f) + cubicTo(0.364583f, 24.1863f, 0f, 22.2303f, 0f, 20.3674f) + cubicTo(0f, 14.1578f, 2.01042f, 9.21087f, 6.03125f, 5.52652f) + cubicTo(10.0521f, 1.84217f, 14.7083f, 0f, 20f, 0f) + cubicTo(25.2917f, 0f, 29.9479f, 1.84217f, 33.9688f, 5.52652f) + cubicTo(37.9896f, 9.21087f, 40f, 14.1578f, 40f, 20.3674f) + cubicTo(40f, 22.2303f, 39.6354f, 24.1863f, 38.9062f, 26.2354f) + cubicTo(38.1771f, 28.2846f, 37.1146f, 30.4166f, 35.7188f, 32.6313f) + cubicTo(34.3229f, 34.8461f, 32.5833f, 37.1332f, 30.5f, 39.4929f) + cubicTo(28.4167f, 41.8525f, 26.0208f, 44.2743f, 23.3125f, 46.7581f) + cubicTo(22.8542f, 47.1721f, 22.3333f, 47.4825f, 21.75f, 47.6895f) + cubicTo(21.1667f, 47.8965f, 20.5833f, 48f, 20f, 48f) + close() + } + // Scale and translate the path + val matrix = Matrix().apply { + setScale(scaleX, scaleY) + postTranslate(inset, inset) + } + path.transform(matrix) + return path + } + + private suspend fun loadAvatarImage(avatarData: AvatarData): Image? { + val imageLoader = SingletonImageLoader.get(context) + val request = ImageRequest.Builder(context) + .data(avatarData) + .size(avatarSizePx.toInt()) + // Disable hardware rendering for Canvas + .allowHardware(false) + .build() + + return imageLoader.execute(request).image + } + + private fun Canvas.drawAvatar( + avatarImage: Image?, + avatarData: AvatarData, + borderColor: Color, + backgroundColor: Color, + foregroundColor: Color, + ) { + val centerX = pinWidthPx / 2 + val avatarY = avatarOffsetPx + val avatarRadius = avatarSizePx / 2 + + withSave { + val clipPath = Path().apply { + addCircle(centerX, avatarY + avatarRadius, avatarRadius, Path.Direction.CW) + } + clipPath(clipPath) + if (avatarImage != null) { + // Draw the loaded avatar image + val destRect = RectF( + centerX - avatarRadius, + avatarY, + centerX + avatarRadius, + avatarY + avatarSizePx + ) + drawBitmap(avatarImage.toBitmap(), null, destRect, null) + } else { + // Fallback: draw initial letter circle + drawInitialLetterAvatar( + avatarData = avatarData, + centerX = centerX, + centerY = avatarY + avatarRadius, + radius = avatarRadius, + foreground = foregroundColor.toArgb(), + background = backgroundColor.toArgb() + ) + } + } + val paintBorder = Paint().apply { + color = borderColor.toArgb() + style = Paint.Style.STROKE + strokeWidth = strokeWidthPx + isAntiAlias = true + } + drawCircle(centerX, avatarY + avatarRadius, avatarRadius, paintBorder) + } + + private fun Canvas.drawInitialLetterAvatar( + avatarData: AvatarData, + centerX: Float, + centerY: Float, + radius: Float, + foreground: Int, + background: Int, + ) { + // Draw background circle + drawCircle(centerX, centerY, radius, Paint().apply { + color = background + style = Paint.Style.FILL + isAntiAlias = true + }) + // Draw initial letter + val textPaint = Paint().apply { + color = foreground + textSize = radius * 1.2f + textAlign = Paint.Align.CENTER + isAntiAlias = true + isFakeBoldText = true + } + // Center text vertically + val textBounds = Rect() + textPaint.getTextBounds(avatarData.initialLetter, 0, 1, textBounds) + val textY = centerY + textBounds.height() / 2f + drawText(avatarData.initialLetter, centerX, textY, textPaint) + } + + private fun Canvas.drawDot(dotColor: Color) { + if (dotColor == Color.Transparent) return + + val centerX = pinWidthPx / 2 + // Position dot in the center of the circular part of the pin + val centerY = avatarOffsetPx + avatarSizePx / 2 + + drawCircle(centerX, centerY, dotRadiusPx, Paint().apply { + color = dotColor.toArgb() + style = Paint.Style.FILL + isAntiAlias = true + }) + } } @PreviewsDayNight From fa9f0a93c04aa34df0f5ce4d75380d45390abbd3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 6 Mar 2026 13:19:09 +0100 Subject: [PATCH 023/103] Improve LocationPin rendering with caching mechanism --- .../designsystem/components/LocationPin.kt | 232 ++++++++++-------- .../components/avatar/internal/ImageAvatar.kt | 8 +- 2 files changed, 128 insertions(+), 112 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index 75129f6795..9fc0d1d27e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.runtime.produceState +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -35,7 +36,10 @@ import androidx.compose.ui.unit.dp import androidx.core.graphics.createBitmap import androidx.core.graphics.withSave import coil3.Image +import coil3.ImageLoader import coil3.SingletonImageLoader +import coil3.asImage +import coil3.memory.MemoryCache import coil3.request.ImageRequest import coil3.request.allowHardware import coil3.toBitmap @@ -46,6 +50,13 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +private val PIN_WIDTH = 42.dp +private val PIN_HEIGHT = PIN_WIDTH * 1.2f +private val AVATAR_SIZE = PIN_WIDTH - 10.dp +private val CONTENT_OFFSET = 5.dp +private val DOT_RADIUS = 6.dp +private val STROKE_WIDTH = 1.dp + /** * Variants of location pin markers. */ @@ -86,21 +97,23 @@ fun LocationPin( fun rememberLocationPinBitmap(variant: PinVariant): ImageBitmap? { val context = LocalContext.current val density = LocalDensity.current + val imageLoader = SingletonImageLoader.get(context) val colors = pinColors(variant) - return produceState(initialValue = null, variant, colors) { - val renderer = LocationPinRenderer(context, density) - val bitmap = renderer.renderPin(variant, colors) - value = bitmap.asImageBitmap() + val cacheKey = rememberCacheKey(variant) + return produceState(initialValue = null, cacheKey) { + val memoryCacheKey = MemoryCache.Key(cacheKey) + val cached = imageLoader.memoryCache?.get(memoryCacheKey) + if (cached != null) { + value = cached.image.toBitmap().asImageBitmap() + } else { + val dimensions = PinDimensions(density) + val bitmap = LocationPinRenderer.renderPin(variant, colors, dimensions, context, imageLoader) + imageLoader.memoryCache?.set(memoryCacheKey, MemoryCache.Value(bitmap.asImage())) + value = bitmap.asImageBitmap() + } }.value } -private val PIN_WIDTH = 42.dp -private val PIN_HEIGHT = PIN_WIDTH * 1.2f -private val AVATAR_SIZE = PIN_WIDTH - 10.dp -private val CONTENT_OFFSET = 5.dp -private val DOT_RADIUS = 6.dp -private val STROKE_WIDTH = 1.dp - @Composable private fun pinColors(variant: PinVariant): PinColors { return when (variant) { @@ -148,7 +161,7 @@ private fun pinColors(variant: PinVariant): PinColors { /** * Color configuration for rendering a location pin. */ -data class PinColors( +private data class PinColors( val fill: Color, val stroke: Color, val dot: Color, @@ -158,20 +171,37 @@ data class PinColors( ) /** - * Renders location pins to bitmaps using Canvas operations. - * Uses Coil for avatar loading with proper memory management. + * Pre-calculated pixel dimensions for rendering a location pin. */ -class LocationPinRenderer( - private val context: Context, - private val density: Density, -) { - // Dimensions in pixels - private val pinWidthPx = with(density) { PIN_WIDTH.toPx() } - private val pinHeightPx = with(density) { PIN_HEIGHT.toPx() } - private val avatarSizePx = with(density) { AVATAR_SIZE.toPx() } - private val avatarOffsetPx = with(density) { CONTENT_OFFSET.toPx() } - private val dotRadiusPx = with(density) { DOT_RADIUS.toPx() } - private val strokeWidthPx = with(density) { STROKE_WIDTH.toPx() } +private class PinDimensions(density: Density) { + val pinWidth = with(density) { PIN_WIDTH.toPx() } + val pinHeight = with(density) { PIN_HEIGHT.toPx() } + val avatarSize: Float = with(density) { AVATAR_SIZE.toPx() } + val avatarOffset: Float = with(density) { CONTENT_OFFSET.toPx() } + val dotRadius: Float = with(density) { DOT_RADIUS.toPx() } + val strokeWidth: Float = with(density) { STROKE_WIDTH.toPx() } +} + +/** + * Renders location pins to bitmaps using Canvas operations. + * Uses Coil for avatar loading. + * Paint objects are shared across all renders. + */ +private object LocationPinRenderer { + // Shared Paint objects to avoid allocations + private val fillPaint = Paint().apply { + style = Paint.Style.FILL + isAntiAlias = true + } + private val strokePaint = Paint().apply { + style = Paint.Style.STROKE + isAntiAlias = true + } + private val textPaint = Paint().apply { + textAlign = Paint.Align.CENTER + isAntiAlias = true + isFakeBoldText = true + } /** * Renders a pin variant to bitmap. Suspending for async avatar loading. @@ -179,56 +209,50 @@ class LocationPinRenderer( suspend fun renderPin( variant: PinVariant, colors: PinColors, + dimensions: PinDimensions, + context: Context, + imageLoader: ImageLoader, ): Bitmap { - val bitmap = createBitmap(pinWidthPx.toInt(), pinHeightPx.toInt()) + val bitmap = createBitmap(dimensions.pinWidth.toInt(), dimensions.pinHeight.toInt()) val canvas = Canvas(bitmap) - // Draw pin shape (fill + stroke) - canvas.drawPinShape(colors.fill, colors.stroke) + canvas.drawPinShape(colors.fill, colors.stroke, dimensions) when (variant) { is PinVariant.UserLocation -> { - val avatarImage = loadAvatarImage(variant.avatarData) + val avatarImage = loadAvatarImage(variant.avatarData, context, imageLoader) canvas.drawAvatar( avatarImage = avatarImage, avatarData = variant.avatarData, borderColor = colors.avatarStroke, backgroundColor = colors.avatarBackground, - foregroundColor = colors.avatarForeground + foregroundColor = colors.avatarForeground, + dimensions = dimensions, ) } PinVariant.PinnedLocation, - PinVariant.StaleLocation -> canvas.drawDot(colors.dot) + PinVariant.StaleLocation -> canvas.drawDot(colors.dot, dimensions) } return bitmap } - private fun Canvas.drawPinShape(fillColor: Color, strokeColor: Color) { - val path = createPinPath() - // Fill - drawPath(path, Paint().apply { - color = fillColor.toArgb() - style = Paint.Style.FILL - isAntiAlias = true - }) - // Stroke - drawPath(path, Paint().apply { - color = strokeColor.toArgb() - style = Paint.Style.STROKE - strokeWidth = strokeWidthPx - isAntiAlias = true - }) + private fun Canvas.drawPinShape(fillColor: Color, strokeColor: Color, dimensions: PinDimensions) { + val path = createPinPath(dimensions) + fillPaint.color = fillColor.toArgb() + drawPath(path, fillPaint) + strokePaint.color = strokeColor.toArgb() + strokePaint.strokeWidth = dimensions.strokeWidth + drawPath(path, strokePaint) } /** - * Creates the teardrop-shaped pin path. + * Updates the teardrop-shaped pin path to match dimensions. * Based on SVG path with dimensions 40x48 (ratio 1:1.2). - * Scales automatically to fit the actual size. */ - private fun createPinPath(): Path { + private fun createPinPath(dimensions: PinDimensions): Path { val svgWidth = 40f val svgHeight = 48f - val inset = strokeWidthPx / 2 - val scaleX = (pinWidthPx - strokeWidthPx) / svgWidth - val scaleY = (pinHeightPx - strokeWidthPx) / svgHeight + val inset = dimensions.strokeWidth / 2 + val scaleX = (dimensions.pinWidth - dimensions.strokeWidth) / svgWidth + val scaleY = (dimensions.pinHeight - dimensions.strokeWidth) / svgHeight val path = Path().apply { moveTo(20f, 48f) @@ -250,7 +274,6 @@ class LocationPinRenderer( cubicTo(21.1667f, 47.8965f, 20.5833f, 48f, 20f, 48f) close() } - // Scale and translate the path val matrix = Matrix().apply { setScale(scaleX, scaleY) postTranslate(inset, inset) @@ -259,15 +282,16 @@ class LocationPinRenderer( return path } - private suspend fun loadAvatarImage(avatarData: AvatarData): Image? { - val imageLoader = SingletonImageLoader.get(context) + private suspend fun loadAvatarImage( + avatarData: AvatarData, + context: Context, + imageLoader: ImageLoader, + ): Image? { val request = ImageRequest.Builder(context) .data(avatarData) - .size(avatarSizePx.toInt()) // Disable hardware rendering for Canvas .allowHardware(false) .build() - return imageLoader.execute(request).image } @@ -277,29 +301,34 @@ class LocationPinRenderer( borderColor: Color, backgroundColor: Color, foregroundColor: Color, + dimensions: PinDimensions, ) { - val centerX = pinWidthPx / 2 - val avatarY = avatarOffsetPx - val avatarRadius = avatarSizePx / 2 + val centerX = dimensions.pinWidth / 2 + val avatarY = dimensions.avatarOffset + val avatarRadius = dimensions.avatarSize / 2 withSave { - val clipPath = Path().apply { - addCircle(centerX, avatarY + avatarRadius, avatarRadius, Path.Direction.CW) - } - clipPath(clipPath) if (avatarImage != null) { - // Draw the loaded avatar image + val bitmap = avatarImage.toBitmap() + // Calculate centered square crop (ContentScale.Crop behavior) + val srcSize = minOf(bitmap.width, bitmap.height) + val srcX = (bitmap.width - srcSize) / 2 + val srcY = (bitmap.height - srcSize) / 2 + val srcRect = Rect(srcX, srcY, srcX + srcSize, srcY + srcSize) val destRect = RectF( centerX - avatarRadius, avatarY, centerX + avatarRadius, - avatarY + avatarSizePx + avatarY + dimensions.avatarSize ) - drawBitmap(avatarImage.toBitmap(), null, destRect, null) + val clipPath = Path().apply { + addCircle(centerX, avatarY + avatarRadius, avatarRadius, Path.Direction.CW) + } + clipPath(clipPath) + drawBitmap(bitmap, srcRect, destRect, null) } else { - // Fallback: draw initial letter circle drawInitialLetterAvatar( - avatarData = avatarData, + initialLetter = avatarData.initialLetter, centerX = centerX, centerY = avatarY + avatarRadius, radius = avatarRadius, @@ -308,56 +337,35 @@ class LocationPinRenderer( ) } } - val paintBorder = Paint().apply { - color = borderColor.toArgb() - style = Paint.Style.STROKE - strokeWidth = strokeWidthPx - isAntiAlias = true - } - drawCircle(centerX, avatarY + avatarRadius, avatarRadius, paintBorder) + strokePaint.color = borderColor.toArgb() + strokePaint.strokeWidth = dimensions.strokeWidth + drawCircle(centerX, avatarY + avatarRadius, avatarRadius, strokePaint) } private fun Canvas.drawInitialLetterAvatar( - avatarData: AvatarData, + initialLetter: String, centerX: Float, centerY: Float, radius: Float, foreground: Int, background: Int, ) { - // Draw background circle - drawCircle(centerX, centerY, radius, Paint().apply { - color = background - style = Paint.Style.FILL - isAntiAlias = true - }) - // Draw initial letter - val textPaint = Paint().apply { - color = foreground - textSize = radius * 1.2f - textAlign = Paint.Align.CENTER - isAntiAlias = true - isFakeBoldText = true - } - // Center text vertically + fillPaint.color = background + drawCircle(centerX, centerY, radius, fillPaint) + textPaint.color = foreground + textPaint.textSize = radius * 1.2f val textBounds = Rect() - textPaint.getTextBounds(avatarData.initialLetter, 0, 1, textBounds) + textPaint.getTextBounds(initialLetter, 0, 1, textBounds) val textY = centerY + textBounds.height() / 2f - drawText(avatarData.initialLetter, centerX, textY, textPaint) + drawText(initialLetter, centerX, textY, textPaint) } - private fun Canvas.drawDot(dotColor: Color) { + private fun Canvas.drawDot(dotColor: Color, dimensions: PinDimensions) { if (dotColor == Color.Transparent) return - - val centerX = pinWidthPx / 2 - // Position dot in the center of the circular part of the pin - val centerY = avatarOffsetPx + avatarSizePx / 2 - - drawCircle(centerX, centerY, dotRadiusPx, Paint().apply { - color = dotColor.toArgb() - style = Paint.Style.FILL - isAntiAlias = true - }) + val centerX = dimensions.pinWidth / 2 + val centerY = dimensions.avatarOffset + dimensions.avatarSize / 2 + fillPaint.color = dotColor.toArgb() + drawCircle(centerX, centerY, dimensions.dotRadius, fillPaint) } } @@ -393,3 +401,17 @@ internal fun LocationPinPreview() = ElementPreview { } } } + +@Composable +private fun rememberCacheKey(variant: PinVariant): String { + val isLightTheme = ElementTheme.isLightTheme + val density = LocalDensity.current.density + return remember(isLightTheme, density, variant) { + val pinVariant = when (variant) { + PinVariant.PinnedLocation -> "pin_pinned" + PinVariant.StaleLocation -> "pin_stale" + is PinVariant.UserLocation -> "pin_user_${variant.avatarData.id}_${variant.isLive}" + } + "${pinVariant}_{$isLightTheme}_{$density}" + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt index 10136bb5c1..e626e0f069 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt @@ -33,16 +33,10 @@ internal fun ImageAvatar( forcedAvatarSize: Dp?, modifier: Modifier = Modifier, contentDescription: String? = null, - configureRequest: (ImageRequest.Builder) -> ImageRequest.Builder = { it }, ) { val size = forcedAvatarSize ?: avatarData.size.dp - val request = ImageRequest.Builder(LocalContext.current) - .data(avatarData) - .let(configureRequest) - .build() - SubcomposeAsyncImage( - model = request, + model = avatarData, contentDescription = contentDescription, contentScale = ContentScale.Crop, modifier = modifier From 91626bd217a14960f926d589f062de568ac0e066 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 6 Mar 2026 16:38:06 +0100 Subject: [PATCH 024/103] Start cleaning up location code --- .../impl/common/ui/LocationPinMarkers.kt | 6 +- .../impl/show/ShowLocationPresenter.kt | 34 ++++++++ .../location/impl/show/ShowLocationState.kt | 2 + .../impl/show/ShowLocationStateProvider.kt | 46 +++++++++-- .../location/impl/show/ShowLocationView.kt | 77 +------------------ 5 files changed, 80 insertions(+), 85 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt index 7fce6ab281..762a719cf4 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationPinMarkers.kt @@ -36,6 +36,8 @@ import org.maplibre.spatialk.geojson.Point import org.maplibre.spatialk.geojson.Position import org.maplibre.spatialk.geojson.toJson +private const val LOCATION_MARKER_ID = "LOCATION_MARKER_ID" + /** * Data class representing a marker on the map. * @@ -81,7 +83,7 @@ fun LocationPinMarkers( id = JsonPrimitive(marker.id), geometry = Point(Position(marker.location.lon, marker.location.lat)), properties = mapOf( - "id" to JsonPrimitive(marker.id), + LOCATION_MARKER_ID to JsonPrimitive(marker.id), ) ) } @@ -153,7 +155,7 @@ private fun LocationPinMarkerLayer( SymbolLayer( id = "pin-marker-${marker.id}", source = source, - filter = !feature.has("point_count") and (feature["id"].asString() eq const(marker.id)), + filter = !feature.has("point_count") and (feature[LOCATION_MARKER_ID].asString() eq const(marker.id)), iconImage = image(imageBitmap), iconAnchor = const(SymbolAnchor.Bottom), iconAllowOverlap = const(true), diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index f402b8fac9..9bbfe35b83 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -24,8 +24,13 @@ import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.designsystem.components.PinVariant +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.room.location.AssetType @AssistedInject class ShowLocationPresenter( @@ -88,9 +93,38 @@ class ShowLocationPresenter( } } + val markers = remember(mode) { + when (mode) { + is ShowLocationMode.Static -> { + val pinVariant = if (mode.assetType == AssetType.PIN) { + PinVariant.PinnedLocation + } else { + PinVariant.UserLocation( + avatarData = AvatarData( + id = mode.senderId.value, + name = mode.senderName, + url = mode.senderAvatarUrl, + size = AvatarSize.UserListItem, + ), + isLive = false, + ) + } + listOf( + LocationMarkerData( + id = mode.senderId.value, + location = mode.location, + variant = pinVariant, + ) + ) + } + ShowLocationMode.Live -> emptyList() + } + } + return ShowLocationState( permissionDialog = permissionDialog, mode = mode, + markers = markers, hasLocationPermission = permissionsState.isAnyGranted, isTrackMyLocation = isTrackMyLocation, appName = appName, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 4eefa34053..ec29cd7c54 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -9,10 +9,12 @@ package io.element.android.features.location.impl.show import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.ui.LocationMarkerData data class ShowLocationState( val permissionDialog: Dialog, val mode: ShowLocationMode, + val markers: List, val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, val appName: String, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 4941d8984d..944645fa1f 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -11,6 +11,10 @@ package io.element.android.features.location.impl.show import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.ui.LocationMarkerData +import io.element.android.libraries.designsystem.components.PinVariant +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.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType @@ -50,18 +54,44 @@ class ShowLocationStateProvider : PreviewParameterProvider { fun aShowLocationState( permissionDialog: ShowLocationState.Dialog = ShowLocationState.Dialog.None, mode: ShowLocationMode = aStaticLocationMode(), + markers: List? = null, hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, appName: String = APP_NAME, eventSink: (ShowLocationEvents) -> Unit = {}, -) = ShowLocationState( - permissionDialog = permissionDialog, - mode = mode, - hasLocationPermission = hasLocationPermission, - isTrackMyLocation = isTrackMyLocation, - appName = appName, - eventSink = eventSink, -) +): ShowLocationState { + val effectiveMarkers = markers ?: when (mode) { + is ShowLocationMode.Static -> listOf( + LocationMarkerData( + id = mode.senderId.value, + location = mode.location, + variant = if (mode.assetType == AssetType.PIN) { + PinVariant.PinnedLocation + } else { + PinVariant.UserLocation( + avatarData = AvatarData( + id = mode.senderId.value, + name = mode.senderName, + url = mode.senderAvatarUrl, + size = AvatarSize.UserListItem, + ), + isLive = true, + ) + } + ) + ) + ShowLocationMode.Live -> emptyList() + } + return ShowLocationState( + permissionDialog = permissionDialog, + mode = mode, + markers = effectiveMarkers, + hasLocationPermission = hasLocationPermission, + isTrackMyLocation = isTrackMyLocation, + appName = appName, + eventSink = eventSink, + ) +} fun aStaticLocationMode( location: Location = Location(1.23, 2.34, 4f), diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index d1a3537d7a..8839dca52f 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -15,33 +15,26 @@ import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment 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.location.api.Location import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton -import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck -import io.element.android.libraries.designsystem.components.PinVariant -import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton 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.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.TopAppBar -import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.ui.strings.CommonStrings import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition @@ -51,10 +44,6 @@ import org.maplibre.compose.location.rememberDefaultLocationProvider import org.maplibre.compose.location.rememberNullLocationProvider import org.maplibre.compose.location.rememberUserLocationState import org.maplibre.spatialk.geojson.Position -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt -import kotlin.random.Random import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @@ -105,7 +94,7 @@ fun ShowLocationView( } val scaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false, initialValue = SheetValue.Hidden) + bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded) ) MapBottomSheetScaffold( scaffoldState = scaffoldState, @@ -137,69 +126,7 @@ fun ShowLocationView( locationState = userLocationState, trackUserLocation = state.isTrackMyLocation ) - when (val mode = state.mode) { - is ShowLocationMode.Static -> { - val pinVariant = if (mode.assetType == AssetType.PIN) { - PinVariant.PinnedLocation - } else { - PinVariant.UserLocation( - avatarData = AvatarData(mode.senderId.value, mode.senderName, mode.senderAvatarUrl, AvatarSize.UserListItem), - isLive = true - ) - } - // Generate test markers around the original location - val testMarkers = remember { - buildList { - // Add the original marker - add( - LocationMarkerData( - id = "original", - location = mode.location, - variant = pinVariant - ) - ) - // Generate 10 random points within 50 meters - val radiusInMeters = 50.0 - val metersPerDegreeLat = 111_320.0 - val metersPerDegreeLon = 111_320.0 * cos(Math.toRadians(mode.location.lat)) - val variants = listOf( - PinVariant.StaleLocation, - PinVariant.UserLocation(AvatarData("@alice", "Alice", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@bob", "Bob", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@cassy", "Cassy", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@daisy", "Daisy", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@en", "G", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@f", "H", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@g", "I", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@h", "J", null, AvatarSize.TimelineSender), isLive = true), - PinVariant.UserLocation(AvatarData("@i", "K", null, AvatarSize.TimelineSender), isLive = true), - ) - repeat(10) { index -> - // Random point in a circle using sqrt for uniform distribution - val angle = Random.nextDouble() * 2 * Math.PI - val distance = sqrt(Random.nextDouble()) * radiusInMeters - val latOffset = (distance * cos(angle)) / metersPerDegreeLat - val lonOffset = (distance * sin(angle)) / metersPerDegreeLon - add( - LocationMarkerData( - id = "test_$index", - location = Location( - lat = mode.location.lat + latOffset, - lon = mode.location.lon + lonOffset - ), - variant = variants[index % (variants.size-1)] - ) - ) - } - } - } - LocationPinMarkers(testMarkers) - } - ShowLocationMode.Live -> { - // TODO: Show pins for all active live location sharers - } - } - + LocationPinMarkers(state.markers) }, overlayContent = { LocationFloatingActionButton( From cbec9dbe2c872f9b319f9c3d306d34a87a1e5c14 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 6 Mar 2026 18:37:02 +0100 Subject: [PATCH 025/103] Start implementing location shares sheet content --- features/location/impl/build.gradle.kts | 2 + .../location/impl/common/MapDefaults.kt | 11 +- .../impl/common/ui/LocationShareRow.kt | 143 ++++++++++++++++++ .../impl/common/ui/MapBottomSheetScaffold.kt | 4 +- .../location/impl/show/ShowLocationEvents.kt | 4 +- .../impl/show/ShowLocationPresenter.kt | 41 +++-- .../location/impl/show/ShowLocationState.kt | 18 +++ .../impl/show/ShowLocationStateProvider.kt | 21 +++ .../location/impl/show/ShowLocationView.kt | 58 +++++-- 9 files changed, 271 insertions(+), 31 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index 94f1ea07dd..c7b19fbf59 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -41,9 +41,11 @@ dependencies { implementation(libs.accompanist.permission) implementation(projects.libraries.uiStrings) implementation(projects.libraries.featureflag.api) + implementation(projects.libraries.dateformatter.api) testCommonDependencies(libs, true) testImplementation(projects.libraries.matrix.test) + implementation(projects.libraries.dateformatter.test) testImplementation(projects.libraries.testtags) testImplementation(projects.services.analytics.test) testImplementation(projects.features.messages.test) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt index 6c01c75508..c515ff6c72 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt @@ -10,10 +10,12 @@ package io.element.android.features.location.impl.common import android.Manifest import androidx.compose.ui.Alignment +import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.map.GestureOptions import org.maplibre.compose.map.MapOptions import org.maplibre.compose.map.OrnamentOptions import org.maplibre.compose.map.RenderOptions +import org.maplibre.spatialk.geojson.Position /** * Common configuration values for the map. @@ -64,13 +66,12 @@ object MapDefaults { pulseColor = Color.Black, ) - val centerCameraPosition = CameraPosition.Builder() - .target(LatLng(49.843, 9.902056)) - .zoom(2.7) - .build() - */ + val centerCameraPosition = CameraPosition( + target = Position(49.843, 9.902056), + zoom = 2.7, + ) const val DEFAULT_ZOOM = 15.0 val permissions = listOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt new file mode 100644 index 0000000000..35817a91e8 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +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.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +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.compound.tokens.generated.CompoundIcons +import io.element.android.features.location.api.Location +import io.element.android.features.location.impl.show.LocationShareItem +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType +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.designsystem.theme.components.IconButton +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.location.AssetType +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun LocationShareRow( + item: LocationShareItem, + onShareClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Avatar( + avatarData = item.avatarData, + avatarType = AvatarType.User, + ) + Spacer(modifier = Modifier.width(16.dp)) + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + Text( + text = item.displayName, + style = ElementTheme.typography.fontBodyLgMedium, + color = ElementTheme.colors.textPrimary, + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + if (item.isLive) { + Icon( + imageVector = CompoundIcons.LocationPinSolid(), + contentDescription = null, + tint = ElementTheme.colors.iconAccentPrimary, + modifier = Modifier.size(16.dp), + ) + }else { + val icon = if(item.assetType == AssetType.PIN) CompoundIcons.LocationNavigator() else CompoundIcons.LocationNavigatorCentred() + Icon( + imageVector = icon, + contentDescription = null, + tint = ElementTheme.colors.iconSecondary, + modifier = Modifier.size(16.dp), + ) + + } + Text( + text = item.formattedTimestamp, + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textSecondary, + ) + } + } + IconButton(onClick = onShareClick) { + Icon( + imageVector = CompoundIcons.ShareAndroid(), + contentDescription = stringResource(CommonStrings.action_share), + tint = ElementTheme.colors.iconPrimary, + ) + } + } +} + +@PreviewsDayNight +@Composable +internal fun LocationShareRowPreview() = ElementPreview { + Column { + LocationShareRow( + item = LocationShareItem( + userId = UserId("@alice:matrix.org"), + displayName = "Alice", + avatarData = AvatarData( + id = "@alice:matrix.org", + name = "Alice", + url = null, + size = AvatarSize.UserListItem, + ), + formattedTimestamp = "Shared 1 min ago", + assetType = AssetType.SENDER, + isLive = true, + location = Location(0.0,0.0) + ), + onShareClick = {}, + ) + LocationShareRow( + item = LocationShareItem( + userId = UserId("@bob:matrix.org"), + displayName = "Bob", + avatarData = AvatarData( + id = "@bob:matrix.org", + name = "Bob", + url = null, + size = AvatarSize.UserListItem, + ), + assetType = AssetType.PIN, + formattedTimestamp = "Shared 5 hours ago", + isLive = false, + location = Location(0.0,0.0) + ), + onShareClick = {}, + ) + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt index 78364a6f4e..97ed6baa62 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -88,7 +88,7 @@ fun MapBottomSheetScaffold( sheetSwipeEnabled: Boolean = true, topBar: (@Composable () -> Unit)? = null, snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }, - sheetContent: @Composable ColumnScope.() -> Unit = {}, + sheetContent: @Composable ColumnScope.(PaddingValues) -> Unit = {}, mapContent: @Composable @MaplibreComposable () -> Unit = {}, overlayContent: @Composable BoxScope.(sheetPadding: PaddingValues) -> Unit = {}, ) { @@ -113,7 +113,7 @@ fun MapBottomSheetScaffold( modifier = Modifier, sheetPeekHeight = sheetPeekHeight, sheetContent = { - sheetContent() + sheetContent(sheetPadding) Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars)) }, scaffoldState = scaffoldState, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt index 12f368fa11..672cab9beb 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt @@ -8,8 +8,10 @@ package io.element.android.features.location.impl.show +import io.element.android.features.location.api.Location + sealed interface ShowLocationEvents { - data object Share : ShowLocationEvents + data class Share(val location: Location) : ShowLocationEvents data class TrackMyLocation(val enabled: Boolean) : ShowLocationEvents data object DismissDialog : ShowLocationEvents data object RequestPermissions : ShowLocationEvents diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 9bbfe35b83..b131d0d137 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -27,6 +27,8 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.dateformatter.api.DateFormatter +import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -38,6 +40,7 @@ class ShowLocationPresenter( permissionsPresenterFactory: PermissionsPresenter.Factory, private val locationActions: LocationActions, private val buildMeta: BuildMeta, + private val dateFormatter: DateFormatter, ) : Presenter { @AssistedFactory fun interface Factory { @@ -63,15 +66,8 @@ class ShowLocationPresenter( fun handleEvent(event: ShowLocationEvents) { when (event) { - ShowLocationEvents.Share -> { - when (mode) { - is ShowLocationMode.Static -> { - locationActions.share(mode.location, null) - } - ShowLocationMode.Live -> { - // TODO: Handle sharing for live locations - } - } + is ShowLocationEvents.Share -> { + locationActions.share(event.location, null) } is ShowLocationEvents.TrackMyLocation -> { if (event.enabled) { @@ -121,10 +117,37 @@ class ShowLocationPresenter( } } + val locationShares = remember(mode) { + when (mode) { + is ShowLocationMode.Static -> { + val relativeTime = dateFormatter.format(timestamp = mode.timestamp, mode = DateFormatterMode.Full, useRelative = true) + val formattedTimestamp = "Shared $relativeTime" + listOf( + LocationShareItem( + userId = mode.senderId, + displayName = mode.senderName, + avatarData = AvatarData( + id = mode.senderId.value, + name = mode.senderName, + url = mode.senderAvatarUrl, + size = AvatarSize.UserListItem, + ), + formattedTimestamp = formattedTimestamp, + isLive = false, + assetType = mode.assetType, + location = mode.location, + ) + ) + } + ShowLocationMode.Live -> emptyList() + } + } + return ShowLocationState( permissionDialog = permissionDialog, mode = mode, markers = markers, + locationShares = locationShares, hasLocationPermission = permissionsState.isAnyGranted, isTrackMyLocation = isTrackMyLocation, appName = appName, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index ec29cd7c54..118d7e9f61 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -8,21 +8,39 @@ package io.element.android.features.location.impl.show +import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.ui.LocationMarkerData +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.location.AssetType data class ShowLocationState( val permissionDialog: Dialog, val mode: ShowLocationMode, val markers: List, + val locationShares: List, val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, val appName: String, val eventSink: (ShowLocationEvents) -> Unit, ) { + + val isSheetDraggable = locationShares.any { item -> item.isLive } + sealed interface Dialog { data object None : Dialog data object PermissionRationale : Dialog data object PermissionDenied : Dialog } } + +data class LocationShareItem( + val userId: UserId, + val displayName: String, + val avatarData: AvatarData, + val formattedTimestamp: String, + val location: Location, + val isLive: Boolean, + val assetType: AssetType?, +) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 944645fa1f..a11b317170 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -55,6 +55,7 @@ fun aShowLocationState( permissionDialog: ShowLocationState.Dialog = ShowLocationState.Dialog.None, mode: ShowLocationMode = aStaticLocationMode(), markers: List? = null, + locationSharers: List? = null, hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, appName: String = APP_NAME, @@ -82,10 +83,30 @@ fun aShowLocationState( ) ShowLocationMode.Live -> emptyList() } + val effectiveLocationSharers = locationSharers ?: when (mode) { + is ShowLocationMode.Static -> listOf( + LocationShareItem( + userId = mode.senderId, + displayName = mode.senderName, + avatarData = AvatarData( + id = mode.senderId.value, + name = mode.senderName, + url = mode.senderAvatarUrl, + size = AvatarSize.UserListItem, + ), + formattedTimestamp = "Shared 1 min ago", + isLive = false, + assetType = mode.assetType, + location = mode.location, + ) + ) + ShowLocationMode.Live -> emptyList() + } return ShowLocationState( permissionDialog = permissionDialog, mode = mode, markers = effectiveMarkers, + locationShares = effectiveLocationSharers, hasLocationPermission = hasLocationPermission, isTrackMyLocation = isTrackMyLocation, appName = appName, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 8839dca52f..0193e52827 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -8,13 +8,16 @@ package io.element.android.features.location.impl.show +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding +import androidx.compose.material3.BottomSheetDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -25,10 +28,13 @@ import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog +import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.LocationPinMarkers +import io.element.android.features.location.impl.common.ui.LocationShareRow import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck +import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -36,6 +42,7 @@ import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.coroutines.launch import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.rememberCameraState @@ -72,9 +79,7 @@ fun ShowLocationView( target = Position(latitude = mode.location.lat, longitude = mode.location.lon), zoom = MapDefaults.DEFAULT_ZOOM ) - ShowLocationMode.Live -> CameraPosition( - zoom = MapDefaults.DEFAULT_ZOOM - ) + ShowLocationMode.Live -> MapDefaults.centerCameraPosition } val cameraState = rememberCameraState(firstPosition = initialPosition) val locationProvider = if (state.hasLocationPermission) { @@ -94,9 +99,22 @@ fun ShowLocationView( } val scaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded) + bottomSheetState = rememberStandardBottomSheetState(initialValue = + if(state.isSheetDraggable) { + SheetValue.PartiallyExpanded + }else { + SheetValue.Expanded + } + ) ) MapBottomSheetScaffold( + //sheetPeekHeight = 180.dp, + sheetDragHandle = if(state.isSheetDraggable) { + {BottomSheetDefaults.DragHandle()} + } else { + null + }, + sheetSwipeEnabled = state.isSheetDraggable, scaffoldState = scaffoldState, cameraState = cameraState, modifier = modifier, @@ -108,18 +126,30 @@ fun ShowLocationView( onClick = onBackClick, ) }, - actions = { - IconButton( - onClick = { state.eventSink(ShowLocationEvents.Share) } - ) { - Icon( - imageVector = CompoundIcons.ShareAndroid(), - contentDescription = stringResource(CommonStrings.action_share), - ) - } - } ) }, + sheetContent = { sheetPaddings -> + val coroutineScope = rememberCoroutineScope() + Text( + text = "On the map", + style = ElementTheme.typography.fontBodyLgMedium, + color = ElementTheme.colors.textPrimary, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), + ) + state.locationShares.forEach { locationShare -> + LocationShareRow( + item = locationShare, + onShareClick = { state.eventSink(ShowLocationEvents.Share(locationShare.location)) }, + modifier = Modifier.clickable { + state.eventSink(ShowLocationEvents.TrackMyLocation(false)) + val position = CameraPosition(padding = sheetPaddings, target = Position(locationShare.location.lon, locationShare.location.lat), zoom = MapDefaults.DEFAULT_ZOOM) + coroutineScope.launch { + cameraState.animateTo(finalPosition = position) + } + } + ) + } + }, mapContent = { UserLocationPuck( cameraState = cameraState, From 60b262a19ef411c65488e13d8b0adf75f94523f2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 9 Mar 2026 21:19:29 +0100 Subject: [PATCH 026/103] Fix compilation --- .../impl/timeline/model/event/TimelineItemLocationContent.kt | 1 + .../android/libraries/matrix/api/room/location/AssetType.kt | 3 ++- .../android/libraries/matrix/impl/room/location/AssetType.kt | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt index 4d96327bb9..74147c697f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt @@ -40,6 +40,7 @@ data class TimelineItemLocationContent( when (assetType) { AssetType.PIN -> PinVariant.PinnedLocation AssetType.SENDER, + AssetType.UNKNOWN, null -> PinVariant.UserLocation(avatarData = senderAvatar(), isLive = false) } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/AssetType.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/AssetType.kt index 42d384fd74..ea65d61bdf 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/AssetType.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/AssetType.kt @@ -10,5 +10,6 @@ package io.element.android.libraries.matrix.api.room.location enum class AssetType { SENDER, - PIN + PIN, + UNKNOWN } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt index 40a55cede1..a88a2524c2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt @@ -14,9 +14,11 @@ import org.matrix.rustcomponents.sdk.AssetType as RustAssetType fun AssetType.into(): RustAssetType = when (this) { AssetType.SENDER -> RustAssetType.SENDER AssetType.PIN -> RustAssetType.PIN + AssetType.UNKNOWN -> RustAssetType.UNKNOWN } fun RustAssetType.into(): AssetType = when(this){ RustAssetType.SENDER -> AssetType.SENDER RustAssetType.PIN -> AssetType.PIN + RustAssetType.UNKNOWN -> AssetType.UNKNOWN } From 4bfe467ac1c5d53fa7ddb1c02eb39fd50f900996 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 9 Mar 2026 21:20:06 +0100 Subject: [PATCH 027/103] Remove local maplibre compose library --- libraries/maplibre-compose/build.gradle.kts | 28 -- .../libraries/maplibre/compose/CameraMode.kt | 48 ---- .../compose/CameraMoveStartedReason.kt | 48 ---- .../maplibre/compose/CameraPositionState.kt | 179 ------------- .../libraries/maplibre/compose/IconAnchor.kt | 39 --- .../libraries/maplibre/compose/MapApplier.kt | 57 ---- .../libraries/maplibre/compose/MapLibreMap.kt | 247 ------------------ .../maplibre/compose/MapLibreMapComposable.kt | 30 --- .../maplibre/compose/MapLocationSettings.kt | 31 --- .../compose/MapSymbolManagerSettings.kt | 22 -- .../maplibre/compose/MapUiSettings.kt | 32 --- .../libraries/maplibre/compose/MapUpdater.kt | 153 ----------- .../libraries/maplibre/compose/Symbol.kt | 114 -------- 13 files changed, 1028 deletions(-) delete mode 100644 libraries/maplibre-compose/build.gradle.kts delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMode.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMoveStartedReason.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraPositionState.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/IconAnchor.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapApplier.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMap.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMapComposable.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLocationSettings.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapSymbolManagerSettings.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUiSettings.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUpdater.kt delete mode 100644 libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/Symbol.kt diff --git a/libraries/maplibre-compose/build.gradle.kts b/libraries/maplibre-compose/build.gradle.kts deleted file mode 100644 index 5552aae37f..0000000000 --- a/libraries/maplibre-compose/build.gradle.kts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * 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") - id("kotlin-parcelize") -} - -android { - namespace = "io.element.android.libraries.maplibre.compose" - - kotlin { - compilerOptions { - explicitApi() - } - } -} - -dependencies { - api(libs.maplibre) - api(libs.maplibre.ktx) - api(libs.maplibre.annotation) -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMode.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMode.kt deleted file mode 100644 index 8ef02f5bbc..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMode.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.Immutable -import org.maplibre.android.location.modes.CameraMode as InternalCameraMode - -@Immutable -public enum class CameraMode { - NONE, - NONE_COMPASS, - NONE_GPS, - TRACKING, - TRACKING_COMPASS, - TRACKING_GPS, - TRACKING_GPS_NORTH; - - @InternalCameraMode.Mode - internal fun toInternal(): Int = when (this) { - NONE -> InternalCameraMode.NONE - NONE_COMPASS -> InternalCameraMode.NONE_COMPASS - NONE_GPS -> InternalCameraMode.NONE_GPS - TRACKING -> InternalCameraMode.TRACKING - TRACKING_COMPASS -> InternalCameraMode.TRACKING_COMPASS - TRACKING_GPS -> InternalCameraMode.TRACKING_GPS - TRACKING_GPS_NORTH -> InternalCameraMode.TRACKING_GPS_NORTH - } - - internal companion object { - fun fromInternal(@InternalCameraMode.Mode mode: Int): CameraMode = when (mode) { - InternalCameraMode.NONE -> NONE - InternalCameraMode.NONE_COMPASS -> NONE_COMPASS - InternalCameraMode.NONE_GPS -> NONE_GPS - InternalCameraMode.TRACKING -> TRACKING - InternalCameraMode.TRACKING_COMPASS -> TRACKING_COMPASS - InternalCameraMode.TRACKING_GPS -> TRACKING_GPS - InternalCameraMode.TRACKING_GPS_NORTH -> TRACKING_GPS_NORTH - else -> error("Unknown camera mode: $mode") - } - } -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMoveStartedReason.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMoveStartedReason.kt deleted file mode 100644 index 2683de1655..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraMoveStartedReason.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.Immutable -import org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener.REASON_API_ANIMATION -import org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener.REASON_API_GESTURE -import org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener.REASON_DEVELOPER_ANIMATION - -/** - * Enumerates the different reasons why the map camera started to move. - * - * Based on enum values from https://docs.maptiler.com/maplibre-gl-native-android/org.maplibre.android.maps/#oncameramovestartedlistener. - * - * [NO_MOVEMENT_YET] is used as the initial state before any map movement has been observed. - * - * [UNKNOWN] is used to represent when an unsupported integer value is provided to [fromInt] - this - * may be a new constant value from the Maps SDK that isn't supported by maps-compose yet, in which - * case this library should be updated to include a new enum value for that constant. - */ -@Immutable -public enum class CameraMoveStartedReason(public val value: Int) { - UNKNOWN(-2), - NO_MOVEMENT_YET(-1), - GESTURE(REASON_API_GESTURE), - API_ANIMATION(REASON_API_ANIMATION), - DEVELOPER_ANIMATION(REASON_DEVELOPER_ANIMATION); - - public companion object { - /** - * Converts from the Maps SDK [org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener] - * constants to [CameraMoveStartedReason], or returns [UNKNOWN] if there is no such - * [CameraMoveStartedReason] for the given [value]. - * - * See https://docs.maptiler.com/maplibre-gl-native-android/org.maplibre.android.maps/#oncameramovestartedlistener. - */ - public fun fromInt(value: Int): CameraMoveStartedReason { - return values().firstOrNull { it.value == value } ?: return UNKNOWN - } - } -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraPositionState.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraPositionState.kt deleted file mode 100644 index 1999526718..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/CameraPositionState.kt +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import android.location.Location -import android.os.Parcelable -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.runtime.staticCompositionLocalOf -import kotlinx.parcelize.Parcelize -import org.maplibre.android.camera.CameraPosition -import org.maplibre.android.camera.CameraUpdateFactory -import org.maplibre.android.maps.MapLibreMap -import org.maplibre.android.maps.Projection - -/** - * Create and [rememberSaveable] a [CameraPositionState] using [CameraPositionState.Saver]. - * [init] will be called when the [CameraPositionState] is first created to configure its - * initial state. - */ -@Composable -public inline fun rememberCameraPositionState( - crossinline init: CameraPositionState.() -> Unit = {} -): CameraPositionState = rememberSaveable(saver = CameraPositionState.Saver) { - CameraPositionState().apply(init) -} - -/** - * A state object that can be hoisted to control and observe the map's camera state. - * A [CameraPositionState] may only be used by a single [MapLibreMap] composable at a time - * as it reflects instance state for a single view of a map. - * - * @param position the initial camera position - * @param cameraMode the initial camera mode - */ -public class CameraPositionState( - position: CameraPosition = CameraPosition.Builder().build(), - cameraMode: CameraMode = CameraMode.NONE, -) { - /** - * Whether the camera is currently moving or not. This includes any kind of movement: - * panning, zooming, or rotation. - */ - public var isMoving: Boolean by mutableStateOf(false) - internal set - - /** - * The reason for the start of the most recent camera moment, or - * [CameraMoveStartedReason.NO_MOVEMENT_YET] if the camera hasn't moved yet or - * [CameraMoveStartedReason.UNKNOWN] if an unknown constant is received from the Maps SDK. - */ - public var cameraMoveStartedReason: CameraMoveStartedReason by mutableStateOf( - CameraMoveStartedReason.NO_MOVEMENT_YET - ) - internal set - - /** - * Returns the current [Projection] to be used for converting between screen - * coordinates and lat/lng. - */ - public val projection: Projection? - get() = map?.projection - - /** - * Local source of truth for the current camera position. - * While [map] is non-null this reflects the current position of [map] as it changes. - * While [map] is null it reflects the last known map position, or the last value set by - * explicitly setting [position]. - */ - internal var rawPosition by mutableStateOf(position) - - /** - * Current position of the camera on the map. - */ - public var position: CameraPosition - get() = rawPosition - set(value) { - synchronized(lock) { - val map = map - if (map == null) { - rawPosition = value - } else { - map.moveCamera(CameraUpdateFactory.newCameraPosition(value)) - } - } - } - - /** - * Local source of truth for the current camera mode. - * While [map] is non-null this reflects the current camera mode as it changes. - * While [map] is null it reflects the last known camera mode, or the last value set by - * explicitly setting [cameraMode]. - */ - internal var rawCameraMode by mutableStateOf(cameraMode) - - /** - * Current tracking mode of the camera. - */ - public var cameraMode: CameraMode - get() = rawCameraMode - set(value) { - synchronized(lock) { - val map = map - if (map == null) { - rawCameraMode = value - } else { - map.locationComponent.cameraMode = value.toInternal() - } - } - } - - /** - * The user's last available location. - */ - public var location: Location? by mutableStateOf(null) - internal set - - // Used to perform side effects thread-safely. - // Guards all mutable properties that are not `by mutableStateOf`. - private val lock = Unit - - // The map currently associated with this CameraPositionState. - // Guarded by `lock`. - private var map: MapLibreMap? by mutableStateOf(null) - - // The current map is set and cleared by side effect. - // There can be only one associated at a time. - internal fun setMap(map: MapLibreMap?) { - synchronized(lock) { - if (this.map == null && map == null) return - if (this.map != null && map != null) { - error("CameraPositionState may only be associated with one MapLibreMap at a time") - } - this.map = map - if (map == null) { - isMoving = false - } else { - map.moveCamera(CameraUpdateFactory.newCameraPosition(position)) - map.locationComponent.cameraMode = cameraMode.toInternal() - } - } - } - - public companion object { - /** - * The default saver implementation for [CameraPositionState]. - */ - public val Saver: Saver = Saver( - save = { SaveableCameraPositionData(it.position, it.cameraMode.toInternal()) }, - restore = { CameraPositionState(it.position, CameraMode.fromInternal(it.cameraMode)) } - ) - } -} - -/** Provides the [CameraPositionState] used by the map. */ -internal val LocalCameraPositionState = staticCompositionLocalOf { CameraPositionState() } - -/** The current [CameraPositionState] used by the map. */ -public val currentCameraPositionState: CameraPositionState - @[MapLibreMapComposable ReadOnlyComposable Composable] - get() = LocalCameraPositionState.current - -@Parcelize -public data class SaveableCameraPositionData( - val position: CameraPosition, - val cameraMode: Int -) : Parcelable diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/IconAnchor.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/IconAnchor.kt deleted file mode 100644 index e46dcdcf65..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/IconAnchor.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.Immutable -import org.maplibre.android.style.layers.Property - -@Immutable -public enum class IconAnchor { - CENTER, - LEFT, - RIGHT, - TOP, - BOTTOM, - TOP_LEFT, - TOP_RIGHT, - BOTTOM_LEFT, - BOTTOM_RIGHT; - - @Property.ICON_ANCHOR - internal fun toInternal(): String = when (this) { - CENTER -> Property.ICON_ANCHOR_CENTER - LEFT -> Property.ICON_ANCHOR_LEFT - RIGHT -> Property.ICON_ANCHOR_RIGHT - TOP -> Property.ICON_ANCHOR_TOP - BOTTOM -> Property.ICON_ANCHOR_BOTTOM - TOP_LEFT -> Property.ICON_ANCHOR_TOP_LEFT - TOP_RIGHT -> Property.ICON_ANCHOR_TOP_RIGHT - BOTTOM_LEFT -> Property.ICON_ANCHOR_BOTTOM_LEFT - BOTTOM_RIGHT -> Property.ICON_ANCHOR_BOTTOM_RIGHT - } -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapApplier.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapApplier.kt deleted file mode 100644 index f8fd64c537..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapApplier.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.AbstractApplier -import org.maplibre.android.maps.MapLibreMap -import org.maplibre.android.maps.Style -import org.maplibre.android.plugins.annotation.SymbolManager - -internal interface MapNode { - fun onAttached() {} - fun onRemoved() {} - fun onCleared() {} -} - -private object MapNodeRoot : MapNode - -internal class MapApplier( - val map: MapLibreMap, - val style: Style, - val symbolManager: SymbolManager, -) : AbstractApplier(MapNodeRoot) { - private val decorations = mutableListOf() - - override fun onClear() { - symbolManager.deleteAll() - decorations.forEach { it.onCleared() } - decorations.clear() - } - - override fun insertBottomUp(index: Int, instance: MapNode) { - decorations.add(index, instance) - instance.onAttached() - } - - override fun insertTopDown(index: Int, instance: MapNode) { - // insertBottomUp is preferred - } - - override fun move(from: Int, to: Int, count: Int) { - decorations.move(from, to, count) - } - - override fun remove(index: Int, count: Int) { - repeat(count) { - decorations[index + it].onRemoved() - } - decorations.remove(index, count) - } -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMap.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMap.kt deleted file mode 100644 index 62c29fbd04..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMap.kt +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import android.content.ComponentCallbacks2 -import android.content.Context -import android.content.res.Configuration -import android.os.Bundle -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Composition -import androidx.compose.runtime.CompositionContext -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCompositionContext -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.viewinterop.AndroidView -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import kotlinx.collections.immutable.ImmutableMap -import kotlinx.collections.immutable.persistentMapOf -import kotlinx.coroutines.awaitCancellation -import org.maplibre.android.MapLibre -import org.maplibre.android.maps.MapLibreMap -import org.maplibre.android.maps.MapView -import org.maplibre.android.maps.Style -import org.maplibre.android.plugins.annotation.SymbolManager -import kotlin.coroutines.resume -import kotlin.coroutines.suspendCoroutine - -/** - * A compose container for a MapLibre [MapView]. - * - * Heavily inspired by https://github.com/googlemaps/android-maps-compose - * - * @param styleUri a URI where to asynchronously fetch a style for the map - * @param modifier Modifier to be applied to the MapLibreMap - * @param images images added to the map's style to be later used with [Symbol] - * @param cameraPositionState the [CameraPositionState] to be used to control or observe the map's - * camera state - * @param uiSettings the [MapUiSettings] to be used for UI-specific settings on the map - * @param symbolManagerSettings the [MapSymbolManagerSettings] to be used for symbol manager settings - * @param locationSettings the [MapLocationSettings] to be used for location settings - * @param content the content of the map - */ -@Composable -public fun MapLibreMap( - styleUri: String, - modifier: Modifier = Modifier, - images: ImmutableMap = persistentMapOf(), - cameraPositionState: CameraPositionState = rememberCameraPositionState(), - uiSettings: MapUiSettings = DefaultMapUiSettings, - symbolManagerSettings: MapSymbolManagerSettings = DefaultMapSymbolManagerSettings, - locationSettings: MapLocationSettings = DefaultMapLocationSettings, - content: (@Composable @MapLibreMapComposable () -> Unit)? = null, -) { - // When in preview, early return a Box with the received modifier preserving layout - if (LocalInspectionMode.current) { - @Suppress("ModifierReused") // False positive, the modifier is not reused due to the early return. - Box( - modifier = modifier.background(Color.DarkGray) - ) { - Text("[Map]", modifier = Modifier.align(Alignment.Center)) - } - return - } - - val context = LocalContext.current - val mapView = remember { - MapLibre.getInstance(context) - MapView(context) - } - - @Suppress("ModifierReused") - AndroidView(modifier = modifier, factory = { mapView }) - MapLifecycle(mapView) - - // rememberUpdatedState and friends are used here to make these values observable to - // the subcomposition without providing a new content function each recomposition - val currentCameraPositionState by rememberUpdatedState(cameraPositionState) - val currentUiSettings by rememberUpdatedState(uiSettings) - val currentMapLocationSettings by rememberUpdatedState(locationSettings) - val currentSymbolManagerSettings by rememberUpdatedState(symbolManagerSettings) - - val parentComposition = rememberCompositionContext() - val currentContent by rememberUpdatedState(content) - - LaunchedEffect(styleUri, images) { - disposingComposition { - parentComposition.newComposition( - context = context, - mapView = mapView, - styleUri = styleUri, - images = images, - ) { - MapUpdater( - cameraPositionState = currentCameraPositionState, - uiSettings = currentUiSettings, - locationSettings = currentMapLocationSettings, - symbolManagerSettings = currentSymbolManagerSettings, - ) - CompositionLocalProvider( - LocalCameraPositionState provides cameraPositionState, - ) { - currentContent?.invoke() - } - } - } - } -} - -private suspend inline fun disposingComposition(factory: () -> Composition) { - val composition = factory() - try { - awaitCancellation() - } finally { - composition.dispose() - } -} - -private suspend inline fun CompositionContext.newComposition( - context: Context, - mapView: MapView, - styleUri: String, - images: ImmutableMap, - noinline content: @Composable () -> Unit -): Composition { - val map = mapView.awaitMap() - val style = map.awaitStyle(context, styleUri, images) - val symbolManager = SymbolManager(mapView, map, style) - return Composition( - MapApplier(map, style, symbolManager), - this - ).apply { - setContent(content) - } -} - -private suspend inline fun MapView.awaitMap(): MapLibreMap = suspendCoroutine { continuation -> - getMapAsync { map -> - continuation.resume(map) - } -} - -private suspend inline fun MapLibreMap.awaitStyle( - context: Context, - styleUri: String, - images: ImmutableMap, -): Style = suspendCoroutine { continuation -> - setStyle( - Style.Builder().apply { - fromUri(styleUri) - images.forEach { (id, drawableRes) -> - withImage(id, checkNotNull(context.getDrawable(drawableRes)) { - "Drawable resource $drawableRes with id $id not found" - }) - } - } - ) { style -> - continuation.resume(style) - } -} - -/** - * Registers lifecycle observers to the local [MapView]. - */ -@Composable -private fun MapLifecycle(mapView: MapView) { - val context = LocalContext.current - val lifecycle = LocalLifecycleOwner.current.lifecycle - val previousState = remember { mutableStateOf(Lifecycle.Event.ON_CREATE) } - DisposableEffect(context, lifecycle, mapView) { - val mapLifecycleObserver = mapView.lifecycleObserver(previousState) - val callbacks = mapView.componentCallbacks() - - lifecycle.addObserver(mapLifecycleObserver) - context.registerComponentCallbacks(callbacks) - - onDispose { - lifecycle.removeObserver(mapLifecycleObserver) - context.unregisterComponentCallbacks(callbacks) - } - } - DisposableEffect(mapView) { - onDispose { - mapView.onDestroy() - mapView.removeAllViews() - } - } -} - -private fun MapView.lifecycleObserver(previousState: MutableState): LifecycleEventObserver = - LifecycleEventObserver { _, event -> - event.targetState - when (event) { - Lifecycle.Event.ON_CREATE -> { - // Skip calling mapView.onCreate if the lifecycle did not go through onDestroy - in - // this case the MapLibreMap composable also doesn't leave the composition. So, - // recreating the map does not restore state properly which must be avoided. - if (previousState.value != Lifecycle.Event.ON_STOP) { - this.onCreate(Bundle()) - } - } - Lifecycle.Event.ON_START -> this.onStart() - Lifecycle.Event.ON_RESUME -> this.onResume() - Lifecycle.Event.ON_PAUSE -> this.onPause() - Lifecycle.Event.ON_STOP -> this.onStop() - Lifecycle.Event.ON_DESTROY -> { - // handled in onDispose - } - Lifecycle.Event.ON_ANY -> error("ON_ANY should never be used") - } - previousState.value = event - } - -private fun MapView.componentCallbacks(): ComponentCallbacks2 = - object : ComponentCallbacks2 { - override fun onConfigurationChanged(config: Configuration) = Unit - - @Suppress("OVERRIDE_DEPRECATION") - override fun onLowMemory() = Unit - - override fun onTrimMemory(level: Int) { - // We call the `MapView.onLowMemory` method for any memory trim level - this@componentCallbacks.onLowMemory() - } - } diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMapComposable.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMapComposable.kt deleted file mode 100644 index c819dee711..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLibreMapComposable.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.ComposableTargetMarker - -/** - * An annotation that can be used to mark a composable function as being expected to be use in a - * composable function that is also marked or inferred to be marked as a [MapLibreMapComposable]. - * - * This will produce build warnings when [MapLibreMapComposable] composable functions are used outside - * of a [MapLibreMapComposable] content lambda, and vice versa. - */ -@Retention(AnnotationRetention.BINARY) -@ComposableTargetMarker(description = "MapLibre Map Composable") -@Target( - AnnotationTarget.FILE, - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.TYPE, - AnnotationTarget.TYPE_PARAMETER, -) -public annotation class MapLibreMapComposable diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLocationSettings.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLocationSettings.kt deleted file mode 100644 index 7fb777aeba..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapLocationSettings.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.ui.graphics.Color - -internal val DefaultMapLocationSettings = MapLocationSettings() - -/** - * Data class for UI-related settings on the map. - * - * Note: Should not be a data class if in need of maintaining binary compatibility - * on future changes. See: https://jakewharton.com/public-api-challenges-in-kotlin/ - */ -public data class MapLocationSettings( - public val locationEnabled: Boolean = false, - public val backgroundTintColor: Color = Color.Unspecified, - public val foregroundTintColor: Color = Color.Unspecified, - public val backgroundStaleTintColor: Color = Color.Unspecified, - public val foregroundStaleTintColor: Color = Color.Unspecified, - public val accuracyColor: Color = Color.Unspecified, - public val pulseEnabled: Boolean = false, - public val pulseColor: Color = Color.Unspecified -) diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapSymbolManagerSettings.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapSymbolManagerSettings.kt deleted file mode 100644 index 93c7b2118b..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapSymbolManagerSettings.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -internal val DefaultMapSymbolManagerSettings = MapSymbolManagerSettings() - -/** - * Data class for UI-related settings on the map. - * - * Note: Should not be a data class if in need of maintaining binary compatibility - * on future changes. See: https://jakewharton.com/public-api-challenges-in-kotlin/ - */ -public data class MapSymbolManagerSettings( - public val iconAllowOverlap: Boolean = false, -) diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUiSettings.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUiSettings.kt deleted file mode 100644 index edee9b4dc5..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUiSettings.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import android.view.Gravity -import androidx.compose.ui.graphics.Color - -internal val DefaultMapUiSettings = MapUiSettings() - -/** - * Data class for UI-related settings on the map. - * - * Note: Should not be a data class if in need of maintaining binary compatibility - * on future changes. See: https://jakewharton.com/public-api-challenges-in-kotlin/ - */ -public data class MapUiSettings( - public val compassEnabled: Boolean = true, - public val rotationGesturesEnabled: Boolean = true, - public val scrollGesturesEnabled: Boolean = true, - public val tiltGesturesEnabled: Boolean = true, - public val zoomGesturesEnabled: Boolean = true, - public val logoGravity: Int = Gravity.BOTTOM, - public val attributionGravity: Int = Gravity.BOTTOM, - public val attributionTintColor: Color = Color.Unspecified, -) diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUpdater.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUpdater.kt deleted file mode 100644 index a07a596fe3..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapUpdater.kt +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ -@file:Suppress("MatchingDeclarationName") - -package io.element.android.libraries.maplibre.compose - -import android.annotation.SuppressLint -import android.content.Context -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ComposeNode -import androidx.compose.runtime.currentComposer -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import org.maplibre.android.location.LocationComponentActivationOptions -import org.maplibre.android.location.LocationComponentOptions -import org.maplibre.android.location.OnCameraTrackingChangedListener -import org.maplibre.android.location.engine.LocationEngineRequest -import org.maplibre.android.maps.MapLibreMap -import org.maplibre.android.maps.Style - -private const val LOCATION_REQUEST_INTERVAL = 750L - -internal class MapPropertiesNode( - val map: MapLibreMap, - style: Style, - context: Context, - cameraPositionState: CameraPositionState, - locationSettings: MapLocationSettings, -) : MapNode { - init { - map.locationComponent.activateLocationComponent( - LocationComponentActivationOptions.Builder(context, style) - .locationComponentOptions( - LocationComponentOptions.builder(context) - .backgroundTintColor(locationSettings.backgroundTintColor.toArgb()) - .foregroundTintColor(locationSettings.foregroundTintColor.toArgb()) - .backgroundStaleTintColor(locationSettings.backgroundStaleTintColor.toArgb()) - .foregroundStaleTintColor(locationSettings.foregroundStaleTintColor.toArgb()) - .accuracyColor(locationSettings.accuracyColor.toArgb()) - .pulseEnabled(locationSettings.pulseEnabled) - .pulseColor(locationSettings.pulseColor.toArgb()) - .build() - ) - .locationEngineRequest( - LocationEngineRequest.Builder(LOCATION_REQUEST_INTERVAL) - .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY) - .setFastestInterval(LOCATION_REQUEST_INTERVAL) - .build() - ) - .build() - ) - cameraPositionState.setMap(map) - } - - var cameraPositionState = cameraPositionState - set(value) { - if (value == field) return - field.setMap(null) - field = value - value.setMap(map) - } - - override fun onAttached() { - map.addOnCameraIdleListener { - cameraPositionState.isMoving = false - // addOnCameraIdleListener is only invoked when the camera position - // is changed via .animate(). To handle updating state when .move() - // is used, it's necessary to set the camera's position here as well - cameraPositionState.rawPosition = map.cameraPosition - // Updating user location on every camera move due to lack of a better location updates API. - cameraPositionState.location = map.locationComponent.lastKnownLocation - } - map.addOnCameraMoveCancelListener { - cameraPositionState.isMoving = false - } - map.addOnCameraMoveStartedListener { - cameraPositionState.cameraMoveStartedReason = CameraMoveStartedReason.fromInt(it) - cameraPositionState.isMoving = true - } - map.addOnCameraMoveListener { - cameraPositionState.rawPosition = map.cameraPosition - // Updating user location on every camera move due to lack of a better location updates API. - cameraPositionState.location = map.locationComponent.lastKnownLocation - } - map.locationComponent.addOnCameraTrackingChangedListener(object : OnCameraTrackingChangedListener { - override fun onCameraTrackingDismissed() {} - - override fun onCameraTrackingChanged(currentMode: Int) { - cameraPositionState.rawCameraMode = CameraMode.fromInternal(currentMode) - } - }) - } - - override fun onRemoved() { - cameraPositionState.setMap(null) - } - - override fun onCleared() { - cameraPositionState.setMap(null) - } -} - -/** - * Used to keep the primary map properties up to date. This should never leave the map composition. - */ -@SuppressLint("MissingPermission") -@Suppress("NOTHING_TO_INLINE") -@Composable -internal inline fun MapUpdater( - cameraPositionState: CameraPositionState, - locationSettings: MapLocationSettings, - uiSettings: MapUiSettings, - symbolManagerSettings: MapSymbolManagerSettings, -) { - val mapApplier = currentComposer.applier as MapApplier - val map = mapApplier.map - val style = mapApplier.style - val symbolManager = mapApplier.symbolManager - val context = LocalContext.current - ComposeNode( - factory = { - MapPropertiesNode( - map = map, - style = style, - context = context, - cameraPositionState = cameraPositionState, - locationSettings = locationSettings, - ) - }, - update = { - set(locationSettings.locationEnabled) { map.locationComponent.isLocationComponentEnabled = it } - - set(uiSettings.compassEnabled) { map.uiSettings.isCompassEnabled = it } - set(uiSettings.rotationGesturesEnabled) { map.uiSettings.isRotateGesturesEnabled = it } - set(uiSettings.scrollGesturesEnabled) { map.uiSettings.isScrollGesturesEnabled = it } - set(uiSettings.tiltGesturesEnabled) { map.uiSettings.isTiltGesturesEnabled = it } - set(uiSettings.zoomGesturesEnabled) { map.uiSettings.isZoomGesturesEnabled = it } - set(uiSettings.logoGravity) { map.uiSettings.logoGravity = it } - set(uiSettings.attributionGravity) { map.uiSettings.attributionGravity = it } - set(uiSettings.attributionTintColor) { map.uiSettings.setAttributionTintColor(it.toArgb()) } - - set(symbolManagerSettings.iconAllowOverlap) { symbolManager.iconAllowOverlap = it } - - update(cameraPositionState) { this.cameraPositionState = it } - } - ) -} diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/Symbol.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/Symbol.kt deleted file mode 100644 index e6a5c3f632..0000000000 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/Symbol.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * Copyright 2021 Google LLC - * - * 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.maplibre.compose - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ComposeNode -import androidx.compose.runtime.currentComposer -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import org.maplibre.android.geometry.LatLng -import org.maplibre.android.plugins.annotation.Symbol -import org.maplibre.android.plugins.annotation.SymbolManager -import org.maplibre.android.plugins.annotation.SymbolOptions - -internal class SymbolNode( - val symbolManager: SymbolManager, - val symbol: Symbol, -) : MapNode { - override fun onRemoved() { - symbolManager.delete(symbol) - } - - override fun onCleared() { - symbolManager.delete(symbol) - } -} - -/** - * A state object that can be hoisted to control and observe the symbol state. - * - * @param position the initial symbol position - */ -public class SymbolState( - position: LatLng -) { - /** - * Current position of the symbol. - */ - public var position: LatLng by mutableStateOf(position) - - public companion object { - /** - * The default saver implementation for [SymbolState]. - */ - public val Saver: Saver = Saver( - save = { it.position }, - restore = { SymbolState(it) } - ) - } -} - -@Composable -public fun rememberSymbolState( - position: LatLng = LatLng(0.0, 0.0) -): SymbolState = rememberSaveable(saver = SymbolState.Saver) { - SymbolState(position) -} - -/** - * A composable for a symbol on the map. - * - * @param iconId an id of an image from the current [Style] - * @param state the [SymbolState] to be used to control or observe the symbol - * state such as its position and info window - * @param iconAnchor the anchor for the symbol image - */ -@Composable -@MapLibreMapComposable -public fun Symbol( - iconId: String, - state: SymbolState = rememberSymbolState(), - iconAnchor: IconAnchor? = null, -) { - val mapApplier = currentComposer.applier as MapApplier - val symbolManager = mapApplier.symbolManager - ComposeNode( - factory = { - SymbolNode( - symbolManager = symbolManager, - symbol = symbolManager.create( - SymbolOptions().apply { - withLatLng(state.position) - withIconImage(iconId) - iconAnchor?.let { withIconAnchor(it.toInternal()) } - } - ), - ) - }, - update = { - update(state.position) { - this.symbol.latLng = it - symbolManager.update(this.symbol) - } - update(iconId) { - this.symbol.iconImage = it - symbolManager.update(this.symbol) - } - update(iconAnchor) { - this.symbol.iconAnchor = it?.toInternal() - symbolManager.update(this.symbol) - } - } - ) -} From b284984dad97ef187c6ef53760fc4ebfbb6030ba Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 10 Mar 2026 21:48:37 +0100 Subject: [PATCH 028/103] Check location is enabled --- .../common/actions/AndroidLocationActions.kt | 20 +++++++++ .../impl/common/actions/LocationActions.kt | 2 + .../ui/LocationServiceDisabledDialog.kt | 27 ++++++++++++ .../location/impl/share/ShareLocationEvent.kt | 1 + .../impl/share/ShareLocationPresenter.kt | 22 ++++++++-- .../location/impl/share/ShareLocationState.kt | 1 + .../impl/share/ShareLocationStateProvider.kt | 5 +++ .../location/impl/share/ShareLocationView.kt | 5 +++ .../location/impl/show/ShowLocationEvents.kt | 1 + .../impl/show/ShowLocationPresenter.kt | 12 +++++- .../location/impl/show/ShowLocationState.kt | 1 + .../impl/show/ShowLocationStateProvider.kt | 4 ++ .../location/impl/show/ShowLocationView.kt | 41 +++++++++++-------- .../common/actions/FakeLocationActions.kt | 19 ++++++++- 14 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt index 0284c25a0a..d69eb018e1 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt @@ -10,8 +10,11 @@ package io.element.android.features.location.impl.common.actions import android.content.Context import android.content.Intent +import android.location.LocationManager import android.net.Uri +import android.provider.Settings import androidx.annotation.VisibleForTesting +import androidx.core.location.LocationManagerCompat import androidx.core.net.toUri import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding @@ -43,6 +46,23 @@ class AndroidLocationActions( override fun openSettings() { context.openAppSettingsPage() } + + override fun isLocationEnabled(): Boolean { + val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager + return LocationManagerCompat.isLocationEnabled(locationManager) + } + + override fun openLocationSettings() { + runCatchingExceptions { + val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) + }.onSuccess { + Timber.v("Open location settings succeed") + }.onFailure { + Timber.e(it, "Open location settings failed") + } + } } // Ref: https://developer.android.com/guide/components/intents-common#ViewMap diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt index cd9efbd261..c4c5db40d0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt @@ -13,4 +13,6 @@ import io.element.android.features.location.api.Location interface LocationActions { fun share(location: Location, label: String?) fun openSettings() + fun isLocationEnabled(): Boolean + fun openLocationSettings() } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt new file mode 100644 index 0000000000..5184845632 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +internal fun LocationServiceDisabledDialog( + onContinue: () -> Unit, + onDismiss: () -> Unit, +) { + ConfirmationDialog( + content = "Location services are disabled. Please enable them in your device settings to use this feature.", + onSubmitClick = onContinue, + onDismiss = onDismiss, + submitText = stringResource(CommonStrings.action_continue), + cancelText = stringResource(CommonStrings.action_cancel), + ) +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index eb641df9fb..7e68ecf358 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -25,4 +25,5 @@ sealed interface ShareLocationEvent { data object DismissDialog : ShareLocationEvent data object RequestPermissions : ShareLocationEvent data object OpenAppSettings : ShareLocationEvent + data object OpenLocationSettings : ShareLocationEvent } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 63d4b7ce8d..df70cddacb 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -33,12 +33,10 @@ import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.CreateTimelineParams import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.Timeline -import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.launch @@ -89,7 +87,13 @@ class ShareLocationPresenter( shareStaticLocation(event) } ShareLocationEvent.StartTrackingUserPosition -> when { - permissionsState.isAnyGranted -> trackUserPosition = true + permissionsState.isAnyGranted -> { + if (!locationActions.isLocationEnabled()) { + dialogState = ShareLocationState.Dialog.LocationServiceDisabled + } else { + trackUserPosition = true + } + } permissionsState.shouldShowRationale -> dialogState = ShareLocationState.Dialog.PermissionRationale else -> dialogState = ShareLocationState.Dialog.PermissionDenied } @@ -99,9 +103,19 @@ class ShareLocationPresenter( locationActions.openSettings() dialogState = ShareLocationState.Dialog.None } + ShareLocationEvent.OpenLocationSettings -> { + locationActions.openLocationSettings() + dialogState = ShareLocationState.Dialog.None + } ShareLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) ShareLocationEvent.ShowLiveLocationDurationPicker -> dialogState = when { - permissionsState.isAnyGranted -> ShareLocationState.Dialog.LiveLocationDuration + permissionsState.isAnyGranted -> { + if (!locationActions.isLocationEnabled()) { + ShareLocationState.Dialog.LocationServiceDisabled + } else { + ShareLocationState.Dialog.LiveLocationDuration + } + } permissionsState.shouldShowRationale -> ShareLocationState.Dialog.PermissionRationale else -> ShareLocationState.Dialog.PermissionDenied } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 547bb99856..c204357a7a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -23,6 +23,7 @@ data class ShareLocationState( data object None : Dialog data object PermissionRationale : Dialog data object PermissionDenied : Dialog + data object LocationServiceDisabled : Dialog data object LiveLocationDuration : Dialog } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index 0d3c448f15..71b143fcef 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -32,6 +32,11 @@ class ShareLocationStateProvider : PreviewParameterProvider trackUserPosition = false, hasLocationPermission = false, ), + aShareLocationState( + permissionDialog = ShareLocationState.Dialog.LocationServiceDisabled, + trackUserPosition = false, + hasLocationPermission = true, + ), aShareLocationState( permissionDialog = ShareLocationState.Dialog.None, trackUserPosition = false, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index a0705221c0..cc88a2d427 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -38,6 +38,7 @@ import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton +import io.element.android.features.location.impl.common.ui.LocationServiceDisabledDialog import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck import io.element.android.libraries.designsystem.components.LocationPin @@ -90,6 +91,10 @@ fun ShareLocationView( onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, appName = state.appName, ) + ShareLocationState.Dialog.LocationServiceDisabled -> LocationServiceDisabledDialog( + onContinue = { state.eventSink(ShareLocationEvent.OpenLocationSettings) }, + onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, + ) ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog( onSelectDuration = { duration -> state.eventSink(ShareLocationEvent.StartLiveLocationShare(duration)) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt index 672cab9beb..52ff87b393 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt @@ -16,4 +16,5 @@ sealed interface ShowLocationEvents { data object DismissDialog : ShowLocationEvents data object RequestPermissions : ShowLocationEvents data object OpenAppSettings : ShowLocationEvents + data object OpenLocationSettings : ShowLocationEvents } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index b131d0d137..2fe40af256 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -72,7 +72,13 @@ class ShowLocationPresenter( is ShowLocationEvents.TrackMyLocation -> { if (event.enabled) { when { - permissionsState.isAnyGranted -> isTrackMyLocation = true + permissionsState.isAnyGranted -> { + if (!locationActions.isLocationEnabled()) { + permissionDialog = ShowLocationState.Dialog.LocationServiceDisabled + } else { + isTrackMyLocation = true + } + } permissionsState.shouldShowRationale -> permissionDialog = ShowLocationState.Dialog.PermissionRationale else -> permissionDialog = ShowLocationState.Dialog.PermissionDenied } @@ -85,6 +91,10 @@ class ShowLocationPresenter( locationActions.openSettings() permissionDialog = ShowLocationState.Dialog.None } + ShowLocationEvents.OpenLocationSettings -> { + locationActions.openLocationSettings() + permissionDialog = ShowLocationState.Dialog.None + } ShowLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 118d7e9f61..2f66dcb26c 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -32,6 +32,7 @@ data class ShowLocationState( data object None : Dialog data object PermissionRationale : Dialog data object PermissionDenied : Dialog + data object LocationServiceDisabled : Dialog } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index a11b317170..a28edf11d0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -30,6 +30,10 @@ class ShowLocationStateProvider : PreviewParameterProvider { aShowLocationState( permissionDialog = ShowLocationState.Dialog.PermissionRationale, ), + aShowLocationState( + permissionDialog = ShowLocationState.Dialog.LocationServiceDisabled, + hasLocationPermission = true, + ), aShowLocationState( hasLocationPermission = true, ), diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 0193e52827..5b7c9b3d08 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -9,6 +9,8 @@ package io.element.android.features.location.impl.show import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.BottomSheetDefaults import androidx.compose.material3.ExperimentalMaterial3Api @@ -23,23 +25,21 @@ 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.compound.theme.ElementTheme import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.ui.LocationServiceDisabledDialog import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog -import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.LocationShareRow import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck -import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.components.button.BackButton 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.designsystem.theme.components.IconButton +import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.launch @@ -72,6 +72,10 @@ fun ShowLocationView( onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, appName = state.appName, ) + ShowLocationState.Dialog.LocationServiceDisabled -> LocationServiceDisabledDialog( + onContinue = { state.eventSink(ShowLocationEvents.OpenLocationSettings) }, + onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, + ) } val initialPosition = when (val mode = state.mode) { @@ -99,18 +103,18 @@ fun ShowLocationView( } val scaffoldState = rememberBottomSheetScaffoldState( - bottomSheetState = rememberStandardBottomSheetState(initialValue = - if(state.isSheetDraggable) { - SheetValue.PartiallyExpanded - }else { - SheetValue.Expanded - } + bottomSheetState = rememberStandardBottomSheetState( + initialValue = + if (state.isSheetDraggable) { + SheetValue.PartiallyExpanded + } else { + SheetValue.Expanded + } ) ) MapBottomSheetScaffold( - //sheetPeekHeight = 180.dp, - sheetDragHandle = if(state.isSheetDraggable) { - {BottomSheetDefaults.DragHandle()} + sheetDragHandle = if (state.isSheetDraggable) { + { BottomSheetDefaults.DragHandle() } } else { null }, @@ -130,8 +134,9 @@ fun ShowLocationView( }, sheetContent = { sheetPaddings -> val coroutineScope = rememberCoroutineScope() + Spacer(Modifier.height(20.dp)) Text( - text = "On the map", + text = stringResource(CommonStrings.screen_static_location_sheet_title), style = ElementTheme.typography.fontBodyLgMedium, color = ElementTheme.colors.textPrimary, modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), @@ -142,7 +147,11 @@ fun ShowLocationView( onShareClick = { state.eventSink(ShowLocationEvents.Share(locationShare.location)) }, modifier = Modifier.clickable { state.eventSink(ShowLocationEvents.TrackMyLocation(false)) - val position = CameraPosition(padding = sheetPaddings, target = Position(locationShare.location.lon, locationShare.location.lat), zoom = MapDefaults.DEFAULT_ZOOM) + val position = CameraPosition( + padding = sheetPaddings, + target = Position(locationShare.location.lon, locationShare.location.lat), + zoom = MapDefaults.DEFAULT_ZOOM + ) coroutineScope.launch { cameraState.animateTo(finalPosition = position) } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt index 94dc972213..795e36fa1a 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt @@ -10,7 +10,9 @@ package io.element.android.features.location.impl.common.actions import io.element.android.features.location.api.Location -class FakeLocationActions : LocationActions { +class FakeLocationActions( + private var isLocationEnabled: Boolean = true, +) : LocationActions { var sharedLocation: Location? = null private set @@ -20,6 +22,9 @@ class FakeLocationActions : LocationActions { var openSettingsInvocationsCount = 0 private set + var openLocationSettingsInvocationsCount = 0 + private set + override fun share(location: Location, label: String?) { sharedLocation = location sharedLabel = label @@ -28,4 +33,16 @@ class FakeLocationActions : LocationActions { override fun openSettings() { openSettingsInvocationsCount++ } + + override fun isLocationEnabled(): Boolean { + return isLocationEnabled + } + + override fun openLocationSettings() { + openLocationSettingsInvocationsCount++ + } + + fun givenLocationEnabled(enabled: Boolean) { + isLocationEnabled = enabled + } } From 22a2bba354f07a11de73069d8b57458a29f58261 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 10 Mar 2026 21:48:54 +0100 Subject: [PATCH 029/103] Fix previews --- .../impl/common/ui/UserLocationPuck.kt | 21 +++++++++++++++++++ .../location/impl/share/ShareLocationView.kt | 17 ++------------- .../location/impl/show/ShowLocationView.kt | 17 ++------------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt index 9d073f8942..9a0623a361 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt @@ -8,14 +8,20 @@ package io.element.android.features.location.impl.common.ui import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import org.maplibre.compose.camera.CameraState +import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.LocationPuck import org.maplibre.compose.location.LocationPuckColors import org.maplibre.compose.location.LocationPuckSizes import org.maplibre.compose.location.LocationTrackingEffect import org.maplibre.compose.location.UserLocationState +import org.maplibre.compose.location.rememberAndroidLocationProvider +import org.maplibre.compose.location.rememberNullLocationProvider +import org.maplibre.compose.location.rememberUserLocationState +import kotlin.time.Duration.Companion.minutes @Composable fun UserLocationPuck( @@ -50,3 +56,18 @@ fun UserLocationPuck( ) } } + +@Composable +fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState { + val isPreview = LocalInspectionMode.current + val locationProvider = if (isPreview || !hasLocationPermission) { + rememberNullLocationProvider() + } else { + rememberAndroidLocationProvider( + updateInterval = 1.minutes, + desiredAccuracy = DesiredAccuracy.Balanced, + minDistanceMeters = 50f, + ) + } + return rememberUserLocationState(locationProvider) +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index cc88a2d427..6fb649a59a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -41,6 +41,7 @@ import io.element.android.features.location.impl.common.ui.LocationFloatingActio import io.element.android.features.location.impl.common.ui.LocationServiceDisabledDialog import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck +import io.element.android.features.location.impl.common.ui.rememberUserLocationState import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -60,13 +61,8 @@ import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState -import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.UserLocationState -import org.maplibre.compose.location.rememberDefaultLocationProvider -import org.maplibre.compose.location.rememberNullLocationProvider -import org.maplibre.compose.location.rememberUserLocationState import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -108,16 +104,7 @@ fun ShareLocationView( bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded) ) val cameraState = rememberCameraState(firstPosition = CameraPosition(zoom = MapDefaults.DEFAULT_ZOOM)) - val locationProvider = if (state.hasLocationPermission) { - rememberDefaultLocationProvider( - updateInterval = 1.minutes, - desiredAccuracy = DesiredAccuracy.Balanced, - minDistanceMeters = 50.0, - ) - } else { - rememberNullLocationProvider() - } - val userLocationState = rememberUserLocationState(locationProvider) + val userLocationState = rememberUserLocationState(state.hasLocationPermission) LaunchedEffect(cameraState.isCameraMoving) { if (cameraState.moveReason == CameraMoveReason.GESTURE) { diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 5b7c9b3d08..eec67ad956 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -36,6 +36,7 @@ import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.LocationShareRow import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck +import io.element.android.features.location.impl.common.ui.rememberUserLocationState import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -46,12 +47,7 @@ import kotlinx.coroutines.launch import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.rememberCameraState -import org.maplibre.compose.location.DesiredAccuracy -import org.maplibre.compose.location.rememberDefaultLocationProvider -import org.maplibre.compose.location.rememberNullLocationProvider -import org.maplibre.compose.location.rememberUserLocationState import org.maplibre.spatialk.geojson.Position -import kotlin.time.Duration.Companion.minutes @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -86,16 +82,7 @@ fun ShowLocationView( ShowLocationMode.Live -> MapDefaults.centerCameraPosition } val cameraState = rememberCameraState(firstPosition = initialPosition) - val locationProvider = if (state.hasLocationPermission) { - rememberDefaultLocationProvider( - updateInterval = 1.minutes, - desiredAccuracy = DesiredAccuracy.Balanced, - minDistanceMeters = 50.0, - ) - } else { - rememberNullLocationProvider() - } - val userLocationState = rememberUserLocationState(locationProvider) + val userLocationState = rememberUserLocationState(state.hasLocationPermission) LaunchedEffect(cameraState.isCameraMoving) { if (cameraState.moveReason == CameraMoveReason.GESTURE) { state.eventSink(ShowLocationEvents.TrackMyLocation(false)) From e664fb0a61758c9f0520535b28809b2982c300c1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 10:28:36 +0100 Subject: [PATCH 030/103] Make sure zoom is at least DEFAULT_ZOOM when following user position --- .../features/location/impl/common/ui/UserLocationPuck.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt index 9a0623a361..f014debe08 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme +import io.element.android.features.location.impl.common.MapDefaults import org.maplibre.compose.camera.CameraState import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.LocationPuck @@ -33,7 +34,12 @@ fun UserLocationPuck( locationState = locationState, enabled = trackUserLocation, ) { - cameraState.updateFromLocation() + val finalPosition = cameraState.position.copy( + target = currentLocation.position, + bearing = currentLocation.bearing ?: cameraState.position.bearing, + zoom = cameraState.position.zoom.coerceAtLeast(MapDefaults.DEFAULT_ZOOM) + ) + cameraState.animateTo(finalPosition) } val location = locationState.location if (location != null) { From 7b305e34efa52099d8fd9848e04801001a3647ee Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 10:29:20 +0100 Subject: [PATCH 031/103] Set LocationShareRow max lines to Text components --- .../features/location/impl/common/ui/LocationShareRow.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt index 35817a91e8..ec059b61b3 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt @@ -19,6 +19,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons @@ -62,6 +63,8 @@ fun LocationShareRow( text = item.displayName, style = ElementTheme.typography.fontBodyLgMedium, color = ElementTheme.colors.textPrimary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, ) Row( verticalAlignment = Alignment.CenterVertically, @@ -82,12 +85,13 @@ fun LocationShareRow( tint = ElementTheme.colors.iconSecondary, modifier = Modifier.size(16.dp), ) - } Text( text = item.formattedTimestamp, style = ElementTheme.typography.fontBodySmRegular, color = ElementTheme.colors.textSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, ) } } From 392fa9de9b5edb3357e6c8a2547f5f78e94ecdaa Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 11:53:36 +0100 Subject: [PATCH 032/103] Add Constraints check for permissions and GPS check --- .../impl/common/LocationConstraintsCheck.kt | 45 +++++++ .../location/impl/common/MapDefaults.kt | 40 +----- .../impl/common/PermissionDeniedDialog.kt | 29 ----- .../impl/common/PermissionRationaleDialog.kt | 29 ----- .../common/actions/AndroidLocationActions.kt | 2 +- .../impl/common/actions/LocationActions.kt | 2 +- .../common/ui/LocationConstraintsDialog.kt | 55 ++++++++ .../ui/LocationServiceDisabledDialog.kt | 27 ---- .../location/impl/share/ShareLocationEvent.kt | 7 +- .../impl/share/ShareLocationPresenter.kt | 53 ++++---- .../location/impl/share/ShareLocationState.kt | 5 +- .../impl/share/ShareLocationStateProvider.kt | 19 +-- .../location/impl/share/ShareLocationView.kt | 78 +++++------- .../impl/show/ShowLocationPresenter.kt | 34 +++-- .../location/impl/show/ShowLocationState.kt | 11 +- .../impl/show/ShowLocationStateProvider.kt | 22 +--- .../location/impl/show/ShowLocationView.kt | 31 ++--- .../common/LocationConstraintsCheckTest.kt | 79 ++++++++++++ .../common/actions/FakeLocationActions.kt | 2 +- .../DefaultShareLocationEntryPointTest.kt | 4 + .../impl/share/ShareLocationPresenterTest.kt | 2 +- .../impl/show/ShowLocationPresenterTest.kt | 119 ++++++++++++------ .../impl/show/ShowLocationViewTest.kt | 13 +- 23 files changed, 382 insertions(+), 326 deletions(-) create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionDeniedDialog.kt delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionRationaleDialog.kt create mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt delete mode 100644 features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt create mode 100644 features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt new file mode 100644 index 0000000000..51d57713c5 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Element Creations 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.location.impl.common + +import io.element.android.features.location.impl.common.actions.LocationActions +import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState + +sealed interface LocationConstraintsCheckResult { + data object Success : LocationConstraintsCheckResult + data object PermissionRationale : LocationConstraintsCheckResult + data object PermissionDenied : LocationConstraintsCheckResult + data object LocationServiceDisabled : LocationConstraintsCheckResult +} + +fun checkLocationConstraints( + permissionsState: PermissionsState, + locationActions: LocationActions, +): LocationConstraintsCheckResult { + return when { + permissionsState.isAnyGranted -> { + if (locationActions.isLocationEnabled()) { + LocationConstraintsCheckResult.Success + } else { + LocationConstraintsCheckResult.LocationServiceDisabled + } + } + permissionsState.shouldShowRationale -> LocationConstraintsCheckResult.PermissionRationale + else -> LocationConstraintsCheckResult.PermissionDenied + } +} + +fun LocationConstraintsCheckResult.toDialogState(): LocationConstraintsDialogState { + return when (this) { + LocationConstraintsCheckResult.Success -> LocationConstraintsDialogState.None + LocationConstraintsCheckResult.PermissionRationale -> LocationConstraintsDialogState.PermissionRationale + LocationConstraintsCheckResult.PermissionDenied -> LocationConstraintsDialogState.PermissionDenied + LocationConstraintsCheckResult.LocationServiceDisabled -> LocationConstraintsDialogState.LocationServiceDisabled + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt index c515ff6c72..1093e5760a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/MapDefaults.kt @@ -34,43 +34,9 @@ object MapDefaults { ) ) - /* - val uiSettings: MapUiSettings - @Composable - @ReadOnlyComposable - get() = MapUiSettings( - compassEnabled = false, - rotationGesturesEnabled = false, - scrollGesturesEnabled = true, - tiltGesturesEnabled = false, - zoomGesturesEnabled = true, - logoGravity = Gravity.TOP, - attributionGravity = Gravity.TOP, - attributionTintColor = ElementTheme.colors.iconPrimary - ) - - val symbolManagerSettings: MapSymbolManagerSettings - get() = MapSymbolManagerSettings( - iconAllowOverlap = true - ) - - val locationSettings: MapLocationSettings - get() = MapLocationSettings( - locationEnabled = false, - backgroundTintColor = Color.White, - foregroundTintColor = Color.Black, - backgroundStaleTintColor = Color.White, - foregroundStaleTintColor = Color.Black, - accuracyColor = Color.Black, - pulseEnabled = true, - pulseColor = Color.Black, - ) - - */ - - val centerCameraPosition = CameraPosition( - target = Position(49.843, 9.902056), - zoom = 2.7, + val defaultCameraPosition = CameraPosition( + target = Position(0.0, 0.0), + zoom = 0.0, ) const val DEFAULT_ZOOM = 15.0 diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionDeniedDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionDeniedDialog.kt deleted file mode 100644 index 6817f579e5..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionDeniedDialog.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * 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.features.location.impl.common - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -internal fun PermissionDeniedDialog( - onContinue: () -> Unit, - onDismiss: () -> Unit, - appName: String, -) { - ConfirmationDialog( - content = stringResource(CommonStrings.error_missing_location_auth_android, appName), - onSubmitClick = onContinue, - onDismiss = onDismiss, - submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), - ) -} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionRationaleDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionRationaleDialog.kt deleted file mode 100644 index 7aef07e32b..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/PermissionRationaleDialog.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * 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.features.location.impl.common - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -internal fun PermissionRationaleDialog( - onContinue: () -> Unit, - onDismiss: () -> Unit, - appName: String, -) { - ConfirmationDialog( - content = stringResource(CommonStrings.error_missing_location_rationale_android, appName), - onSubmitClick = onContinue, - onDismiss = onDismiss, - submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), - ) -} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt index d69eb018e1..7994a6e6b1 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/AndroidLocationActions.kt @@ -43,7 +43,7 @@ class AndroidLocationActions( } } - override fun openSettings() { + override fun openAppSettings() { context.openAppSettingsPage() } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt index c4c5db40d0..bc8e558c55 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/actions/LocationActions.kt @@ -12,7 +12,7 @@ import io.element.android.features.location.api.Location interface LocationActions { fun share(location: Location, label: String?) - fun openSettings() + fun openAppSettings() fun isLocationEnabled(): Boolean fun openLocationSettings() } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt new file mode 100644 index 0000000000..d42a551254 --- /dev/null +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2026 Element Creations 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.location.impl.common.ui + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog +import io.element.android.libraries.ui.strings.CommonStrings + +sealed interface LocationConstraintsDialogState { + data object None : LocationConstraintsDialogState + data object PermissionRationale : LocationConstraintsDialogState + data object PermissionDenied : LocationConstraintsDialogState + data object LocationServiceDisabled : LocationConstraintsDialogState +} + +@Composable +fun LocationConstraintsDialog( + state: LocationConstraintsDialogState, + appName: String, + onRequestPermissions: () -> Unit, + onOpenAppSettings: () -> Unit, + onOpenLocationSettings: () -> Unit, + onDismiss: () -> Unit, +) { + when (state) { + LocationConstraintsDialogState.None -> Unit + LocationConstraintsDialogState.PermissionRationale -> ConfirmationDialog( + content = stringResource(CommonStrings.error_missing_location_rationale_android, appName), + onSubmitClick = onRequestPermissions, + onDismiss = onDismiss, + submitText = stringResource(CommonStrings.action_continue), + cancelText = stringResource(CommonStrings.action_cancel), + ) + LocationConstraintsDialogState.PermissionDenied -> ConfirmationDialog( + content = stringResource(CommonStrings.error_missing_location_auth_android, appName), + onSubmitClick = onOpenAppSettings, + onDismiss = onDismiss, + submitText = stringResource(CommonStrings.action_continue), + cancelText = stringResource(CommonStrings.action_cancel), + ) + LocationConstraintsDialogState.LocationServiceDisabled -> ConfirmationDialog( + content = "Please enable your GPS to access location-based features.", + onSubmitClick = onOpenLocationSettings, + onDismiss = onDismiss, + submitText = stringResource(CommonStrings.action_continue), + cancelText = stringResource(CommonStrings.action_cancel), + ) + } +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt deleted file mode 100644 index 5184845632..0000000000 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationServiceDisabledDialog.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 Element Creations 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.location.impl.common.ui - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -internal fun LocationServiceDisabledDialog( - onContinue: () -> Unit, - onDismiss: () -> Unit, -) { - ConfirmationDialog( - content = "Location services are disabled. Please enable them in your device settings to use this feature.", - onSubmitClick = onContinue, - onDismiss = onDismiss, - submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), - ) -} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index 7e68ecf358..b95e86084b 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -20,10 +20,11 @@ sealed interface ShareLocationEvent { data object ShowLiveLocationDurationPicker : ShareLocationEvent data class StartLiveLocationShare(val duration: Duration) : ShareLocationEvent - data object StartTrackingUserPosition : ShareLocationEvent - data object StopTrackingUserPosition : ShareLocationEvent + data object StartTrackingUserLocation : ShareLocationEvent + data object StopTrackingUserLocation : ShareLocationEvent data object DismissDialog : ShareLocationEvent - data object RequestPermissions : ShareLocationEvent + + data object RequestPermissions: ShareLocationEvent data object OpenAppSettings : ShareLocationEvent data object OpenLocationSettings : ShareLocationEvent } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index df70cddacb..7ca8cbb7e3 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -21,11 +21,15 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.Composer +import io.element.android.features.location.impl.common.LocationConstraintsCheckResult import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.actions.LocationActions +import io.element.android.features.location.impl.common.checkLocationConstraints import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.toDialogState +import io.element.android.features.location.impl.share.ShareLocationState.Dialog.Constraints import io.element.android.features.messages.api.MessageComposerContext import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.extensions.flatMap @@ -63,7 +67,7 @@ class ShareLocationPresenter( @Composable override fun present(): ShareLocationState { val permissionsState: PermissionsState = permissionsPresenter.present() - var trackUserPosition: Boolean by remember { mutableStateOf(permissionsState.isAnyGranted) } + var trackUserPosition: Boolean by remember { mutableStateOf(permissionsState.isAnyGranted && locationActions.isLocationEnabled()) } val isLiveLocationSharingEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.LiveLocationSharing) }.collectAsState(false) @@ -74,55 +78,46 @@ class ShareLocationPresenter( val currentUser by client.userProfile.collectAsState() val scope = rememberCoroutineScope() - LaunchedEffect(permissionsState.permissions) { - if (permissionsState.isAnyGranted) { - trackUserPosition = true - dialogState = ShareLocationState.Dialog.None - } + fun checkLocationConstraints() { + val locationConstraints = checkLocationConstraints(permissionsState, locationActions) + dialogState = Constraints(locationConstraints.toDialogState()) + trackUserPosition = locationConstraints is LocationConstraintsCheckResult.Success } + LaunchedEffect(permissionsState.permissions) { checkLocationConstraints() } + fun handleEvent(event: ShareLocationEvent) { when (event) { is ShareLocationEvent.ShareStaticLocation -> scope.launch { shareStaticLocation(event) } - ShareLocationEvent.StartTrackingUserPosition -> when { - permissionsState.isAnyGranted -> { - if (!locationActions.isLocationEnabled()) { - dialogState = ShareLocationState.Dialog.LocationServiceDisabled - } else { - trackUserPosition = true - } - } - permissionsState.shouldShowRationale -> dialogState = ShareLocationState.Dialog.PermissionRationale - else -> dialogState = ShareLocationState.Dialog.PermissionDenied - } - ShareLocationEvent.StopTrackingUserPosition -> trackUserPosition = false + ShareLocationEvent.StartTrackingUserLocation -> checkLocationConstraints() + ShareLocationEvent.StopTrackingUserLocation -> trackUserPosition = false ShareLocationEvent.DismissDialog -> dialogState = ShareLocationState.Dialog.None ShareLocationEvent.OpenAppSettings -> { - locationActions.openSettings() + locationActions.openAppSettings() dialogState = ShareLocationState.Dialog.None } ShareLocationEvent.OpenLocationSettings -> { locationActions.openLocationSettings() dialogState = ShareLocationState.Dialog.None } - ShareLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) - ShareLocationEvent.ShowLiveLocationDurationPicker -> dialogState = when { - permissionsState.isAnyGranted -> { - if (!locationActions.isLocationEnabled()) { - ShareLocationState.Dialog.LocationServiceDisabled - } else { - ShareLocationState.Dialog.LiveLocationDuration - } + ShareLocationEvent.ShowLiveLocationDurationPicker -> { + val constraintsResult = checkLocationConstraints(permissionsState, locationActions) + dialogState = if (constraintsResult is LocationConstraintsCheckResult.Success) { + ShareLocationState.Dialog.LiveLocationDuration + } else { + Constraints(constraintsResult.toDialogState()) } - permissionsState.shouldShowRationale -> ShareLocationState.Dialog.PermissionRationale - else -> ShareLocationState.Dialog.PermissionDenied } is ShareLocationEvent.StartLiveLocationShare -> scope.launch { dialogState = ShareLocationState.Dialog.None //room.startLiveLocationShare(event.duration.inWholeMilliseconds) } + ShareLocationEvent.RequestPermissions -> { + dialogState = ShareLocationState.Dialog.None + permissionsState.eventSink(PermissionsEvents.RequestPermissions) + } } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index c204357a7a..72f94d5b06 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -8,6 +8,7 @@ package io.element.android.features.location.impl.share +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.matrix.api.user.MatrixUser data class ShareLocationState( @@ -21,9 +22,7 @@ data class ShareLocationState( ) { sealed interface Dialog { data object None : Dialog - data object PermissionRationale : Dialog - data object PermissionDenied : Dialog - data object LocationServiceDisabled : Dialog + data class Constraints(val state: LocationConstraintsDialogState) : Dialog data object LiveLocationDuration : Dialog } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index 71b143fcef..768d1a5d50 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -9,6 +9,7 @@ package io.element.android.features.location.impl.share import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser @@ -18,37 +19,37 @@ class ShareLocationStateProvider : PreviewParameterProvider override val values: Sequence get() = sequenceOf( aShareLocationState( - permissionDialog = ShareLocationState.Dialog.None, + dialogState = ShareLocationState.Dialog.None, trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.PermissionDenied, + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied), trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.PermissionRationale, + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale), trackUserPosition = false, hasLocationPermission = false, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.LocationServiceDisabled, + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled), trackUserPosition = false, hasLocationPermission = true, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.None, + dialogState = ShareLocationState.Dialog.None, trackUserPosition = false, hasLocationPermission = true, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.None, + dialogState = ShareLocationState.Dialog.None, trackUserPosition = true, hasLocationPermission = true, ), aShareLocationState( - permissionDialog = ShareLocationState.Dialog.LiveLocationDuration, + dialogState = ShareLocationState.Dialog.LiveLocationDuration, trackUserPosition = true, hasLocationPermission = true, canShareLiveLocation = true, @@ -58,14 +59,14 @@ class ShareLocationStateProvider : PreviewParameterProvider private fun aShareLocationState( currentUser: MatrixUser = MatrixUser(UserId("@user:matrix.org")), - permissionDialog: ShareLocationState.Dialog, + dialogState: ShareLocationState.Dialog, trackUserPosition: Boolean, hasLocationPermission: Boolean, canShareLiveLocation: Boolean = false, ): ShareLocationState { return ShareLocationState( currentUser = currentUser, - dialogState = permissionDialog, + dialogState = dialogState, trackUserLocation = trackUserPosition, hasLocationPermission = hasLocationPermission, canShareLiveLocation = canShareLiveLocation, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 6fb649a59a..e5fa9d8c0c 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -35,10 +35,8 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.location.api.Location import io.element.android.features.location.api.internal.centerBottomEdge import io.element.android.features.location.impl.common.MapDefaults -import io.element.android.features.location.impl.common.PermissionDeniedDialog -import io.element.android.features.location.impl.common.PermissionRationaleDialog +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton -import io.element.android.features.location.impl.common.ui.LocationServiceDisabledDialog import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck import io.element.android.features.location.impl.common.ui.rememberUserLocationState @@ -58,7 +56,6 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import org.maplibre.compose.camera.CameraMoveReason -import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState import org.maplibre.compose.location.UserLocationState @@ -71,24 +68,14 @@ fun ShareLocationView( navigateUp: () -> Unit, modifier: Modifier = Modifier, ) { - LaunchedEffect(Unit) { - state.eventSink(ShareLocationEvent.RequestPermissions) - } - - when (state.dialogState) { + when (val dialogState = state.dialogState) { ShareLocationState.Dialog.None -> Unit - ShareLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( - onContinue = { state.eventSink(ShareLocationEvent.OpenAppSettings) }, - onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, + is ShareLocationState.Dialog.Constraints -> LocationConstraintsDialog( + state = dialogState.state, appName = state.appName, - ) - ShareLocationState.Dialog.PermissionRationale -> PermissionRationaleDialog( - onContinue = { state.eventSink(ShareLocationEvent.RequestPermissions) }, - onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, - appName = state.appName, - ) - ShareLocationState.Dialog.LocationServiceDisabled -> LocationServiceDisabledDialog( - onContinue = { state.eventSink(ShareLocationEvent.OpenLocationSettings) }, + onRequestPermissions = { state.eventSink(ShareLocationEvent.RequestPermissions) }, + onOpenAppSettings = { state.eventSink(ShareLocationEvent.OpenAppSettings) }, + onOpenLocationSettings = { state.eventSink(ShareLocationEvent.OpenLocationSettings) }, onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, ) ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog( @@ -103,12 +90,12 @@ fun ShareLocationView( val scaffoldState = rememberBottomSheetScaffoldState( bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded) ) - val cameraState = rememberCameraState(firstPosition = CameraPosition(zoom = MapDefaults.DEFAULT_ZOOM)) + val cameraState = rememberCameraState(firstPosition = MapDefaults.defaultCameraPosition) val userLocationState = rememberUserLocationState(state.hasLocationPermission) LaunchedEffect(cameraState.isCameraMoving) { if (cameraState.moveReason == CameraMoveReason.GESTURE) { - state.eventSink(ShareLocationEvent.StopTrackingUserPosition) + state.eventSink(ShareLocationEvent.StopTrackingUserLocation) } } @@ -159,7 +146,7 @@ fun ShareLocationView( } LocationFloatingActionButton( isMapCenteredOnUser = state.trackUserLocation, - onClick = { state.eventSink(ShareLocationEvent.StartTrackingUserPosition) }, + onClick = { state.eventSink(ShareLocationEvent.StartTrackingUserLocation) }, modifier = Modifier .align(Alignment.TopEnd) .padding(all = 16.dp), @@ -176,39 +163,34 @@ private fun BottomSheetContent( navigateUp: () -> Unit, ) { Spacer(Modifier.height(20.dp)) - SharePinLocationItem( - onClick = { - val positionTarget = cameraState.position.target + val userLocation = userLocationState.location + if (state.trackUserLocation && userLocation != null) { + ShareCurrentLocationItem { state.eventSink( ShareLocationEvent.ShareStaticLocation( - location = Location(lat = positionTarget.latitude, lon = positionTarget.longitude), - isPinned = true + location = Location( + lat = userLocation.position.latitude, + lon = userLocation.position.longitude + ), + isPinned = false ) ) navigateUp() } - ) - ShareCurrentLocationItem( - onClick = { - val userLocation = userLocationState.location - if (state.hasLocationPermission) { - if (userLocation == null) { - // - } else { - state.eventSink( - ShareLocationEvent.ShareStaticLocation( - location = Location( - lat = userLocation.position.latitude, - lon = userLocation.position.longitude - ), - isPinned = false - ) + } else { + SharePinLocationItem( + onClick = { + val positionTarget = cameraState.position.target + state.eventSink( + ShareLocationEvent.ShareStaticLocation( + location = Location(lat = positionTarget.latitude, lon = positionTarget.longitude), + isPinned = true ) - navigateUp() - } + ) + navigateUp() } - } - ) + ) + } if (state.canShareLiveLocation) { ShareLiveLocationItem { state.eventSink(ShareLocationEvent.ShowLiveLocationDurationPicker) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 2fe40af256..c48c2c27d2 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -19,11 +19,15 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.LocationConstraintsCheckResult +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.actions.LocationActions +import io.element.android.features.location.impl.common.checkLocationConstraints import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.toDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta @@ -54,13 +58,13 @@ class ShowLocationPresenter( val permissionsState: PermissionsState = permissionsPresenter.present() var isTrackMyLocation by remember { mutableStateOf(false) } val appName by remember { derivedStateOf { buildMeta.applicationName } } - var permissionDialog: ShowLocationState.Dialog by remember { - mutableStateOf(ShowLocationState.Dialog.None) + var dialogState: LocationConstraintsDialogState by remember { + mutableStateOf(LocationConstraintsDialogState.None) } LaunchedEffect(permissionsState.permissions) { if (permissionsState.isAnyGranted) { - permissionDialog = ShowLocationState.Dialog.None + dialogState = LocationConstraintsDialogState.None } } @@ -71,29 +75,21 @@ class ShowLocationPresenter( } is ShowLocationEvents.TrackMyLocation -> { if (event.enabled) { - when { - permissionsState.isAnyGranted -> { - if (!locationActions.isLocationEnabled()) { - permissionDialog = ShowLocationState.Dialog.LocationServiceDisabled - } else { - isTrackMyLocation = true - } - } - permissionsState.shouldShowRationale -> permissionDialog = ShowLocationState.Dialog.PermissionRationale - else -> permissionDialog = ShowLocationState.Dialog.PermissionDenied - } + val locationConstraints = checkLocationConstraints(permissionsState, locationActions) + isTrackMyLocation = locationConstraints is LocationConstraintsCheckResult.Success + dialogState = locationConstraints.toDialogState() } else { isTrackMyLocation = false } } - ShowLocationEvents.DismissDialog -> permissionDialog = ShowLocationState.Dialog.None + ShowLocationEvents.DismissDialog -> dialogState = LocationConstraintsDialogState.None ShowLocationEvents.OpenAppSettings -> { - locationActions.openSettings() - permissionDialog = ShowLocationState.Dialog.None + locationActions.openAppSettings() + dialogState = LocationConstraintsDialogState.None } ShowLocationEvents.OpenLocationSettings -> { locationActions.openLocationSettings() - permissionDialog = ShowLocationState.Dialog.None + dialogState = LocationConstraintsDialogState.None } ShowLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) } @@ -154,7 +150,7 @@ class ShowLocationPresenter( } return ShowLocationState( - permissionDialog = permissionDialog, + dialogState = dialogState, mode = mode, markers = markers, locationShares = locationShares, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 2f66dcb26c..3a8fcf51de 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -10,13 +10,14 @@ package io.element.android.features.location.impl.show import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType data class ShowLocationState( - val permissionDialog: Dialog, + val dialogState: LocationConstraintsDialogState, val mode: ShowLocationMode, val markers: List, val locationShares: List, @@ -25,15 +26,7 @@ data class ShowLocationState( val appName: String, val eventSink: (ShowLocationEvents) -> Unit, ) { - val isSheetDraggable = locationShares.any { item -> item.isLive } - - sealed interface Dialog { - data object None : Dialog - data object PermissionRationale : Dialog - data object PermissionDenied : Dialog - data object LocationServiceDisabled : Dialog - } } data class LocationShareItem( diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index a28edf11d0..6880ed1bf5 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -11,6 +11,7 @@ package io.element.android.features.location.impl.show import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -25,13 +26,13 @@ class ShowLocationStateProvider : PreviewParameterProvider { get() = sequenceOf( aShowLocationState(), aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionDenied, + constraintsDialogState = LocationConstraintsDialogState.PermissionDenied, ), aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionRationale, + constraintsDialogState = LocationConstraintsDialogState.PermissionRationale, ), aShowLocationState( - permissionDialog = ShowLocationState.Dialog.LocationServiceDisabled, + constraintsDialogState = LocationConstraintsDialogState.LocationServiceDisabled, hasLocationPermission = true, ), aShowLocationState( @@ -41,22 +42,11 @@ class ShowLocationStateProvider : PreviewParameterProvider { hasLocationPermission = true, isTrackMyLocation = true, ), - aShowLocationState( - mode = aStaticLocationMode(senderName = "My favourite place!"), - ), - aShowLocationState( - mode = aStaticLocationMode( - senderName = "For some reason I decided to write a small essay that wraps at just two lines!" - ), - ), - aShowLocationState( - mode = ShowLocationMode.Live, - ), ) } fun aShowLocationState( - permissionDialog: ShowLocationState.Dialog = ShowLocationState.Dialog.None, + constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None, mode: ShowLocationMode = aStaticLocationMode(), markers: List? = null, locationSharers: List? = null, @@ -107,7 +97,7 @@ fun aShowLocationState( ShowLocationMode.Live -> emptyList() } return ShowLocationState( - permissionDialog = permissionDialog, + dialogState = constraintsDialogState, mode = mode, markers = effectiveMarkers, locationShares = effectiveLocationSharers, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index eec67ad956..3d3dc6f5c6 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -27,10 +27,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.api.ShowLocationMode -import io.element.android.features.location.impl.common.ui.LocationServiceDisabledDialog +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.MapDefaults -import io.element.android.features.location.impl.common.PermissionDeniedDialog -import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.LocationShareRow @@ -56,30 +54,21 @@ fun ShowLocationView( onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { - when (state.permissionDialog) { - ShowLocationState.Dialog.None -> Unit - ShowLocationState.Dialog.PermissionDenied -> PermissionDeniedDialog( - onContinue = { state.eventSink(ShowLocationEvents.OpenAppSettings) }, - onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, - appName = state.appName, - ) - ShowLocationState.Dialog.PermissionRationale -> PermissionRationaleDialog( - onContinue = { state.eventSink(ShowLocationEvents.RequestPermissions) }, - onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, - appName = state.appName, - ) - ShowLocationState.Dialog.LocationServiceDisabled -> LocationServiceDisabledDialog( - onContinue = { state.eventSink(ShowLocationEvents.OpenLocationSettings) }, - onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, - ) - } + LocationConstraintsDialog( + state = state.dialogState, + appName = state.appName, + onRequestPermissions = { state.eventSink(ShowLocationEvents.RequestPermissions) }, + onOpenAppSettings = { state.eventSink(ShowLocationEvents.OpenAppSettings) }, + onOpenLocationSettings = { state.eventSink(ShowLocationEvents.OpenLocationSettings) }, + onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, + ) val initialPosition = when (val mode = state.mode) { is ShowLocationMode.Static -> CameraPosition( target = Position(latitude = mode.location.lat, longitude = mode.location.lon), zoom = MapDefaults.DEFAULT_ZOOM ) - ShowLocationMode.Live -> MapDefaults.centerCameraPosition + ShowLocationMode.Live -> MapDefaults.defaultCameraPosition } val cameraState = rememberCameraState(firstPosition = initialPosition) val userLocationState = rememberUserLocationState(state.hasLocationPermission) diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt new file mode 100644 index 0000000000..801d58e5da --- /dev/null +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Element Creations 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.location.impl.common + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.location.impl.aPermissionsState +import io.element.android.features.location.impl.common.actions.FakeLocationActions +import io.element.android.features.location.impl.common.permissions.PermissionsState +import org.junit.Test + +class LocationConstraintsCheckTest { + @Test + fun `checkLocationConstraints returns Success when permissions granted and location enabled`() { + val permissionsState = aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + ) + val locationActions = FakeLocationActions(isLocationEnabled = true) + + val result = checkLocationConstraints(permissionsState, locationActions) + + assertThat(result).isEqualTo(LocationConstraintsCheckResult.Success) + } + + @Test + fun `checkLocationConstraints returns Success when some permissions granted and location enabled`() { + val permissionsState = aPermissionsState( + permissions = PermissionsState.Permissions.SomeGranted, + ) + val locationActions = FakeLocationActions(isLocationEnabled = true) + + val result = checkLocationConstraints(permissionsState, locationActions) + + assertThat(result).isEqualTo(LocationConstraintsCheckResult.Success) + } + + @Test + fun `checkLocationConstraints returns LocationServiceDisabled when permissions granted but location disabled`() { + val permissionsState = aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + ) + val locationActions = FakeLocationActions(isLocationEnabled = false) + + val result = checkLocationConstraints(permissionsState, locationActions) + + assertThat(result).isEqualTo(LocationConstraintsCheckResult.LocationServiceDisabled) + } + + @Test + fun `checkLocationConstraints returns PermissionRationale when permissions denied with rationale`() { + val permissionsState = aPermissionsState( + permissions = PermissionsState.Permissions.NoneGranted, + shouldShowRationale = true, + ) + val locationActions = FakeLocationActions(isLocationEnabled = true) + + val result = checkLocationConstraints(permissionsState, locationActions) + + assertThat(result).isEqualTo(LocationConstraintsCheckResult.PermissionRationale) + } + + @Test + fun `checkLocationConstraints returns PermissionDenied when permissions denied without rationale`() { + val permissionsState = aPermissionsState( + permissions = PermissionsState.Permissions.NoneGranted, + shouldShowRationale = false, + ) + val locationActions = FakeLocationActions(isLocationEnabled = true) + + val result = checkLocationConstraints(permissionsState, locationActions) + + assertThat(result).isEqualTo(LocationConstraintsCheckResult.PermissionDenied) + } + +} diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt index 795e36fa1a..e05787d6a6 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/actions/FakeLocationActions.kt @@ -30,7 +30,7 @@ class FakeLocationActions( sharedLabel = label } - override fun openSettings() { + override fun openAppSettings() { openSettingsInvocationsCount++ } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt index b6161b3a9c..100e660820 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt @@ -14,7 +14,9 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter import io.element.android.features.messages.test.FakeMessageComposerContext +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.services.analytics.test.FakeAnalyticsService @@ -42,6 +44,8 @@ class DefaultShareLocationEntryPointTest { messageComposerContext = FakeMessageComposerContext(), locationActions = FakeLocationActions(), buildMeta = aBuildMeta(), + featureFlagService = FakeFeatureFlagService(), + client = FakeMatrixClient(), ) }, analyticsService = FakeAnalyticsService(), diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 8d34fb99d6..32d862893a 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -228,7 +228,7 @@ class ShareLocationPresenterTest { assertThat(myLocationState.hasLocationPermission).isFalse() // Continue the dialog sends permission request to the permissions presenter - myLocationState.eventSink(ShareLocationEvent.RequestPermissions) + myLocationState.eventSink(ShareLocationEvent.StartTrackingUserLocation) assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions) } } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index df22863c7c..ebbad8e9d1 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -13,12 +13,15 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.location.api.Location +import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.aPermissionsState +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsEvents -import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.libraries.dateformatter.test.FakeDateFormatter +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.delay @@ -33,15 +36,25 @@ class ShowLocationPresenterTest { private val fakePermissionsPresenter = FakePermissionsPresenter() private val fakeLocationActions = FakeLocationActions() private val fakeBuildMeta = aBuildMeta(applicationName = "app name") + private val fakeDateFormatter = FakeDateFormatter() private val location = Location(1.23, 4.56, 7.8f) - private val presenter = ShowLocationPresenter( - permissionsPresenterFactory = object : PermissionsPresenter.Factory { - override fun create(permissions: List): PermissionsPresenter = fakePermissionsPresenter - }, - locationActions = fakeLocationActions, + + private fun createShowLocationPresenter( + mode: ShowLocationMode = ShowLocationMode.Static( + location = location, + senderName = "Alice", + senderId = UserId("@alice:matrix.org"), + senderAvatarUrl = null, + timestamp = System.currentTimeMillis(), + assetType = null, + ), + locationActions: FakeLocationActions = fakeLocationActions, + ) = ShowLocationPresenter( + mode = mode, + permissionsPresenterFactory = { fakePermissionsPresenter }, + locationActions = locationActions, buildMeta = fakeBuildMeta, - location = location, - description = A_DESCRIPTION, + dateFormatter = fakeDateFormatter, ) @Test @@ -54,11 +67,9 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() - assertThat(initialState.location).isEqualTo(location) - assertThat(initialState.description).isEqualTo(A_DESCRIPTION) assertThat(initialState.hasLocationPermission).isFalse() assertThat(initialState.isTrackMyLocation).isFalse() } @@ -74,11 +85,9 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() - assertThat(initialState.location).isEqualTo(location) - assertThat(initialState.description).isEqualTo(A_DESCRIPTION) assertThat(initialState.hasLocationPermission).isFalse() assertThat(initialState.isTrackMyLocation).isFalse() } @@ -89,11 +98,9 @@ class ShowLocationPresenterTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() - assertThat(initialState.location).isEqualTo(location) - assertThat(initialState.description).isEqualTo(A_DESCRIPTION) assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() } @@ -104,11 +111,9 @@ class ShowLocationPresenterTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.SomeGranted)) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() - assertThat(initialState.location).isEqualTo(location) - assertThat(initialState.description).isEqualTo(A_DESCRIPTION) assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() } @@ -117,13 +122,12 @@ class ShowLocationPresenterTest { @Test fun `uses action to share location`() = runTest { moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() - initialState.eventSink(ShowLocationEvents.Share) + initialState.eventSink(ShowLocationEvents.Share(location)) assertThat(fakeLocationActions.sharedLocation).isEqualTo(location) - assertThat(fakeLocationActions.sharedLabel).isEqualTo(A_DESCRIPTION) } } @@ -132,7 +136,7 @@ class ShowLocationPresenterTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isTrue() @@ -149,7 +153,7 @@ class ShowLocationPresenterTest { // Swipe the map to switch mode initialState.eventSink(ShowLocationEvents.TrackMyLocation(false)) val trackLocationDisabledState = awaitItem() - assertThat(trackLocationDisabledState.permissionDialog).isEqualTo(ShowLocationState.Dialog.None) + assertThat(trackLocationDisabledState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(trackLocationDisabledState.isTrackMyLocation).isFalse() assertThat(trackLocationDisabledState.hasLocationPermission).isTrue() } @@ -165,7 +169,7 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { // Skip initial state val initialState = awaitItem() @@ -173,14 +177,14 @@ class ShowLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) val trackLocationState = awaitItem() - assertThat(trackLocationState.permissionDialog).isEqualTo(ShowLocationState.Dialog.PermissionRationale) + assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionRationale) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() // Dismiss the dialog initialState.eventSink(ShowLocationEvents.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShowLocationState.Dialog.None) + assertThat(dialogDismissedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(dialogDismissedState.isTrackMyLocation).isFalse() assertThat(dialogDismissedState.hasLocationPermission).isFalse() } @@ -196,7 +200,7 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { // Skip initial state val initialState = awaitItem() @@ -204,7 +208,7 @@ class ShowLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) val trackLocationState = awaitItem() - assertThat(trackLocationState.permissionDialog).isEqualTo(ShowLocationState.Dialog.PermissionRationale) + assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionRationale) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() @@ -224,7 +228,7 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { // Skip initial state val initialState = awaitItem() @@ -232,14 +236,14 @@ class ShowLocationPresenterTest { // Click on the button to switch mode initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) val trackLocationState = awaitItem() - assertThat(trackLocationState.permissionDialog).isEqualTo(ShowLocationState.Dialog.PermissionDenied) + assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionDenied) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() // Dismiss the dialog initialState.eventSink(ShowLocationEvents.DismissDialog) val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.permissionDialog).isEqualTo(ShowLocationState.Dialog.None) + assertThat(dialogDismissedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(dialogDismissedState.isTrackMyLocation).isFalse() assertThat(dialogDismissedState.hasLocationPermission).isFalse() } @@ -255,7 +259,7 @@ class ShowLocationPresenterTest { ) moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { // Skip initial state val initialState = awaitItem() @@ -267,7 +271,7 @@ class ShowLocationPresenterTest { dialogShownState.eventSink(ShowLocationEvents.OpenAppSettings) val settingsOpenedState = awaitItem() - assertThat(settingsOpenedState.permissionDialog).isEqualTo(ShowLocationState.Dialog.None) + assertThat(settingsOpenedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(fakeLocationActions.openSettingsInvocationsCount).isEqualTo(1) } } @@ -275,14 +279,53 @@ class ShowLocationPresenterTest { @Test fun `application name is in state`() = runTest { moleculeFlow(RecompositionMode.Immediate) { - presenter.present() + createShowLocationPresenter().present() }.test { val initialState = awaitItem() assertThat(initialState.appName).isEqualTo("app name") } } - companion object { - private const val A_DESCRIPTION = "My happy place" + @Test + fun `location service disabled shows dialog`() = runTest { + fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) + fakeLocationActions.givenLocationEnabled(false) + + moleculeFlow(RecompositionMode.Immediate) { + createShowLocationPresenter(locationActions = fakeLocationActions).present() + }.test { + val initialState = awaitItem() + assertThat(initialState.hasLocationPermission).isTrue() + + // Try to track location when location services are disabled + initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + val dialogShownState = awaitItem() + + assertThat(dialogShownState.dialogState).isEqualTo(LocationConstraintsDialogState.LocationServiceDisabled) + assertThat(dialogShownState.isTrackMyLocation).isFalse() + } + } + + @Test + fun `open location settings from dialog`() = runTest { + fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) + fakeLocationActions.givenLocationEnabled(false) + + moleculeFlow(RecompositionMode.Immediate) { + createShowLocationPresenter(locationActions = fakeLocationActions).present() + }.test { + val initialState = awaitItem() + + initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + val dialogShownState = awaitItem() + assertThat(dialogShownState.dialogState).isEqualTo(LocationConstraintsDialogState.LocationServiceDisabled) + + // Open location settings + dialogShownState.eventSink(ShowLocationEvents.OpenLocationSettings) + val settingsOpenedState = awaitItem() + + assertThat(settingsOpenedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) + assertThat(fakeLocationActions.openLocationSettingsInvocationsCount).isEqualTo(1) + } } } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt index 2245360bb2..a70d3441c4 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt @@ -17,6 +17,8 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.location.api.Location +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled @@ -58,7 +60,8 @@ class ShowLocationViewTest { ) val shareContentDescription = rule.activity.getString(CommonStrings.action_share) rule.onNodeWithContentDescription(shareContentDescription).performClick() - eventsRecorder.assertSingle(ShowLocationEvents.Share) + // The default aStaticLocationMode uses Location(1.23, 2.34, 4f) + eventsRecorder.assertSingle(ShowLocationEvents.Share(Location(1.23, 2.34, 4f))) } @Test @@ -79,7 +82,7 @@ class ShowLocationViewTest { val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionDenied, + constraintsDialogState = LocationConstraintsDialogState.PermissionDenied, eventSink = eventsRecorder ), onBackClick = EnsureNeverCalled(), @@ -93,7 +96,7 @@ class ShowLocationViewTest { val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionDenied, + constraintsDialogState = LocationConstraintsDialogState.PermissionDenied, eventSink = eventsRecorder ), onBackClick = EnsureNeverCalled(), @@ -107,7 +110,7 @@ class ShowLocationViewTest { val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionRationale, + constraintsDialogState = LocationConstraintsDialogState.PermissionRationale, eventSink = eventsRecorder ), onBackClick = EnsureNeverCalled(), @@ -121,7 +124,7 @@ class ShowLocationViewTest { val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( - permissionDialog = ShowLocationState.Dialog.PermissionRationale, + constraintsDialogState = LocationConstraintsDialogState.PermissionRationale, eventSink = eventsRecorder ), onBackClick = EnsureNeverCalled(), From 8274ef220d145e7b22e6510fc19a4c763240a355 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 12:31:51 +0100 Subject: [PATCH 033/103] Fix and add tests related to location --- .../impl/share/ShareLocationStateProvider.kt | 14 +- .../impl/share/ShareLocationPresenterTest.kt | 435 ++++++++---------- .../impl/share/ShareLocationViewTest.kt | 163 +++++++ .../show/DefaultShowLocationEntryPointTest.kt | 21 +- .../impl/show/ShowLocationPresenterTest.kt | 62 +-- 5 files changed, 404 insertions(+), 291 deletions(-) create mode 100644 features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index 768d1a5d50..efc7fdc8a1 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -57,12 +57,14 @@ class ShareLocationStateProvider : PreviewParameterProvider ) } -private fun aShareLocationState( +fun aShareLocationState( currentUser: MatrixUser = MatrixUser(UserId("@user:matrix.org")), - dialogState: ShareLocationState.Dialog, - trackUserPosition: Boolean, - hasLocationPermission: Boolean, + dialogState: ShareLocationState.Dialog = ShareLocationState.Dialog.None, + trackUserPosition: Boolean = false, + hasLocationPermission: Boolean = false, canShareLiveLocation: Boolean = false, + appName: String = APP_NAME, + eventSink: (ShareLocationEvent) -> Unit = {}, ): ShareLocationState { return ShareLocationState( currentUser = currentUser, @@ -70,7 +72,7 @@ private fun aShareLocationState( trackUserLocation = trackUserPosition, hasLocationPermission = hasLocationPermission, canShareLiveLocation = canShareLiveLocation, - appName = APP_NAME, - eventSink = {} + appName = appName, + eventSink = eventSink ) } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 32d862893a..b9311188d2 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -20,22 +20,25 @@ import io.element.android.features.location.impl.common.permissions.FakePermissi import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.messages.test.FakeMessageComposerContext +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.Timeline -import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId -import io.element.android.libraries.matrix.test.AN_EVENT_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.core.aBuildMeta import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.timeline.FakeTimeline -import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.services.analytics.test.FakeAnalyticsService 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.delay +import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test @@ -49,9 +52,12 @@ class ShareLocationPresenterTest { private val fakeMessageComposerContext = FakeMessageComposerContext() private val fakeLocationActions = FakeLocationActions() private val fakeBuildMeta = aBuildMeta(applicationName = "app name") + private val fakeFeatureFlagService = FakeFeatureFlagService() + private val fakeMatrixClient = FakeMatrixClient(sessionId = A_USER_ID) private fun createShareLocationPresenter( joinedRoom: JoinedRoom = FakeJoinedRoom(), + locationActions: FakeLocationActions = fakeLocationActions, ): ShareLocationPresenter = ShareLocationPresenter( permissionsPresenterFactory = object : PermissionsPresenter.Factory { override fun create(permissions: List): PermissionsPresenter = fakePermissionsPresenter @@ -60,13 +66,14 @@ class ShareLocationPresenterTest { timelineMode = Timeline.Mode.Live, analyticsService = fakeAnalyticsService, messageComposerContext = fakeMessageComposerContext, - locationActions = fakeLocationActions, + locationActions = locationActions, buildMeta = fakeBuildMeta, + featureFlagService = fakeFeatureFlagService, + client = fakeMatrixClient, ) @Test - fun `initial state with permissions granted`() = runTest { - val shareLocationPresenter = createShareLocationPresenter() + fun `initial state with permissions granted and location enabled`() = runTest { fakePermissionsPresenter.givenState( aPermissionsState( permissions = PermissionsState.Permissions.AllGranted, @@ -74,25 +81,18 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) - assertThat(initialState.hasLocationPermission).isTrue() - - // Swipe the map to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isTrue() + val shareLocationPresenter = createShareLocationPresenter() + shareLocationPresenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.trackUserLocation).isTrue() + assertThat(state.hasLocationPermission).isTrue() + assertThat(state.dialogState).isEqualTo(ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.None)) } } @Test - fun `initial state with permissions partially granted`() = runTest { + fun `initial state with permissions partially granted and location enabled`() = runTest { val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( @@ -104,17 +104,11 @@ class ShareLocationPresenterTest { moleculeFlow(RecompositionMode.Immediate) { shareLocationPresenter.present() }.test { + skipItems(1) val initialState = awaitItem() - assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.SenderLocation) + assertThat(initialState.trackUserLocation).isTrue() assertThat(initialState.hasLocationPermission).isTrue() - - // Swipe the map to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToPinLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isTrue() + assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.None)) } } @@ -131,22 +125,18 @@ class ShareLocationPresenterTest { moleculeFlow(RecompositionMode.Immediate) { shareLocationPresenter.present() }.test { + skipItems(1) val initialState = awaitItem() - assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) + assertThat(initialState.trackUserLocation).isFalse() assertThat(initialState.hasLocationPermission).isFalse() - - // Click on the button to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionDenied) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isFalse() + assertThat(initialState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied) + ) } } @Test - fun `initial state with permissions denied once`() = runTest { + fun `initial state with permissions denied with rationale`() = runTest { val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( @@ -155,25 +145,62 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { + shareLocationPresenter.test { + skipItems(1) val initialState = awaitItem() - assertThat(initialState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(initialState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) + assertThat(initialState.trackUserLocation).isFalse() assertThat(initialState.hasLocationPermission).isFalse() - - // Click on the button to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isFalse() + assertThat(initialState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale) + ) } } @Test - fun `rationale dialog dismiss`() = runTest { + fun `initial state with location services disabled`() = runTest { + val locationActions = FakeLocationActions(isLocationEnabled = false) + val shareLocationPresenter = createShareLocationPresenter(locationActions = locationActions) + fakePermissionsPresenter.givenState( + aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + shouldShowRationale = false, + ) + ) + + shareLocationPresenter.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.trackUserLocation).isFalse() + assertThat(initialState.hasLocationPermission).isTrue() + assertThat(initialState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled) + ) + } + } + + @Test + fun `StopTrackingUserLocation event sets trackUserLocation to false`() = runTest { + val shareLocationPresenter = createShareLocationPresenter() + fakePermissionsPresenter.givenState( + aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + shouldShowRationale = false, + ) + ) + + shareLocationPresenter.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.trackUserLocation).isTrue() + + initialState.eventSink(ShareLocationEvent.StopTrackingUserLocation) + val stoppedState = awaitItem() + assertThat(stoppedState.trackUserLocation).isFalse() + } + } + + @Test + fun `DismissDialog event clears dialog state`() = runTest { val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( @@ -182,30 +209,21 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state + shareLocationPresenter.test { + skipItems(1) val initialState = awaitItem() + assertThat(initialState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale) + ) - // Click on the button to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isFalse() - - // Dismiss the dialog - myLocationState.eventSink(ShareLocationEvent.DismissDialog) - val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(dialogDismissedState.hasLocationPermission).isFalse() + initialState.eventSink(ShareLocationEvent.DismissDialog) + val dismissedState = awaitItem() + assertThat(dismissedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) } } @Test - fun `rationale dialog continue`() = runTest { + fun `RequestPermissions event triggers permission request`() = runTest { val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( @@ -214,27 +232,20 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state + shareLocationPresenter.test { val initialState = awaitItem() + initialState.eventSink(ShareLocationEvent.RequestPermissions) - // Click on the button to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionRationale) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isFalse() + // Wait for dialog to be dismissed + awaitItem() - // Continue the dialog sends permission request to the permissions presenter - myLocationState.eventSink(ShareLocationEvent.StartTrackingUserLocation) assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions) + cancelAndIgnoreRemainingEvents() } } @Test - fun `permission denied dialog dismiss`() = runTest { + fun `OpenAppSettings event opens settings and clears dialog`() = runTest { val shareLocationPresenter = createShareLocationPresenter() fakePermissionsPresenter.givenState( aPermissionsState( @@ -243,31 +254,94 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state + shareLocationPresenter.test { + skipItems(1) val initialState = awaitItem() + initialState.eventSink(ShareLocationEvent.OpenAppSettings) + val settingsOpenedState = awaitItem() - // Click on the button to switch mode - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val myLocationState = awaitItem() - assertThat(myLocationState.dialogState).isEqualTo(ShareLocationState.Dialog.PermissionDenied) - assertThat(myLocationState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(myLocationState.hasLocationPermission).isFalse() - - // Dismiss the dialog - myLocationState.eventSink(ShareLocationEvent.DismissDialog) - val dialogDismissedState = awaitItem() - assertThat(dialogDismissedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(dialogDismissedState.mode).isEqualTo(ShareLocationState.Mode.PinLocation) - assertThat(dialogDismissedState.hasLocationPermission).isFalse() + assertThat(settingsOpenedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) + assertThat(fakeLocationActions.openSettingsInvocationsCount).isEqualTo(1) } } @Test - fun `share sender location`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> + fun `OpenLocationSettings event opens location settings and clears dialog`() = runTest { + val locationActions = FakeLocationActions(isLocationEnabled = false) + val shareLocationPresenter = createShareLocationPresenter(locationActions = locationActions) + fakePermissionsPresenter.givenState( + aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + shouldShowRationale = false, + ) + ) + + shareLocationPresenter.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled) + ) + + initialState.eventSink(ShareLocationEvent.OpenLocationSettings) + val settingsOpenedState = awaitItem() + + assertThat(settingsOpenedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) + assertThat(locationActions.openLocationSettingsInvocationsCount).isEqualTo(1) + } + } + + @Test + fun `ShowLiveLocationDurationPicker shows duration dialog when constraints pass`() = runTest { + val shareLocationPresenter = createShareLocationPresenter() + fakePermissionsPresenter.givenState( + aPermissionsState( + permissions = PermissionsState.Permissions.AllGranted, + shouldShowRationale = false, + ) + ) + + shareLocationPresenter.test { + skipItems(1) + val initialState = awaitItem() + initialState.eventSink(ShareLocationEvent.ShowLiveLocationDurationPicker) + val durationDialogState = awaitItem() + + assertThat(durationDialogState.dialogState).isEqualTo(ShareLocationState.Dialog.LiveLocationDuration) + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `ShowLiveLocationDurationPicker shows constraint dialog when permissions denied`() = runTest { + val shareLocationPresenter = createShareLocationPresenter() + fakePermissionsPresenter.givenState( + aPermissionsState( + permissions = PermissionsState.Permissions.NoneGranted, + shouldShowRationale = false, + ) + ) + + shareLocationPresenter.test { + skipItems(1) + val initialState = awaitItem() + // Dismiss initial dialog + initialState.eventSink(ShareLocationEvent.DismissDialog) + val dismissedState = awaitItem() + + dismissedState.eventSink(ShareLocationEvent.ShowLiveLocationDurationPicker) + val constraintDialogState = awaitItem() + + assertThat(constraintDialogState.dialogState).isEqualTo( + ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied) + ) + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `ShareStaticLocation sends user location`() = runTest { + val sendLocationResult = lambdaRecorder { _: String, _: String, _: String?, _: Int?, _: AssetType?, _: EventId? -> Result.success(Unit) } val joinedRoom = FakeJoinedRoom( @@ -283,29 +357,18 @@ class ShareLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state + shareLocationPresenter.test { + skipItems(1) val initialState = awaitItem() - // Send location initialState.eventSink( ShareLocationEvent.ShareStaticLocation( - cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( - lat = 0.0, - lon = 1.0, - zoom = 2.0, - ), - location = Location( - lat = 3.0, - lon = 4.0, - accuracy = 5.0f, - ) + location = Location(lat = 3.0, lon = 4.0, accuracy = 5.0f), + isPinned = false, ) ) - delay(1) // Wait for the coroutine to finish + advanceUntilIdle() sendLocationResult.assertions().isCalledOnce() .with( @@ -326,12 +389,13 @@ class ShareLocationPresenterTest { messageType = Composer.MessageType.LocationUser, ) ) + cancelAndIgnoreRemainingEvents() } } @Test - fun `share pin location`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> + fun `ShareStaticLocation sends pinned location`() = runTest { + val sendLocationResult = lambdaRecorder { _: String, _: String, _: String?, _: Int?, _: AssetType?, _: EventId? -> Result.success(Unit) } val joinedRoom = FakeJoinedRoom( @@ -342,39 +406,26 @@ class ShareLocationPresenterTest { val shareLocationPresenter = createShareLocationPresenter(joinedRoom) fakePermissionsPresenter.givenState( aPermissionsState( - permissions = PermissionsState.Permissions.NoneGranted, + permissions = PermissionsState.Permissions.AllGranted, shouldShowRationale = false, ) ) - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state + shareLocationPresenter.test { val initialState = awaitItem() - // Send location initialState.eventSink( ShareLocationEvent.ShareStaticLocation( - cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( - lat = 0.0, - lon = 1.0, - zoom = 2.0, - ), - location = Location( - lat = 3.0, - lon = 4.0, - accuracy = 5.0f, - ) + location = Location(lat = 1.0, lon = 2.0, accuracy = 3.0f), + isPinned = true, ) ) - delay(1) // Wait for the coroutine to finish - + advanceUntilIdle() sendLocationResult.assertions().isCalledOnce() .with( - value("Location was shared at geo:0.0,1.0"), - value("geo:0.0,1.0"), + value("Location was shared at geo:1.0,2.0;u=3.0"), + value("geo:1.0,2.0;u=3.0"), value(null), value(15), value(AssetType.PIN), @@ -390,107 +441,7 @@ class ShareLocationPresenterTest { messageType = Composer.MessageType.LocationPin, ) ) - } - } - - @Test - fun `composer context passes through analytics`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> - Result.success(Unit) - } - val joinedRoom = FakeJoinedRoom( - liveTimeline = FakeTimeline().apply { - sendLocationLambda = sendLocationResult - }, - ) - val shareLocationPresenter = createShareLocationPresenter(joinedRoom) - fakePermissionsPresenter.givenState( - aPermissionsState( - permissions = PermissionsState.Permissions.NoneGranted, - shouldShowRationale = false, - ) - ) - fakeMessageComposerContext.apply { - composerMode = MessageComposerMode.Edit( - eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(), - content = "" - ) - } - - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state - val initialState = awaitItem() - - // Send location - initialState.eventSink( - ShareLocationEvent.ShareStaticLocation( - cameraPosition = ShareLocationEvent.ShareStaticLocation.CameraPosition( - lat = 0.0, - lon = 1.0, - zoom = 2.0, - ), - location = null - ) - ) - - delay(1) // Wait for the coroutine to finish - - assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1) - assertThat(fakeAnalyticsService.capturedEvents.last()).isEqualTo( - Composer( - inThread = false, - isEditing = true, - isReply = false, - messageType = Composer.MessageType.LocationPin, - ) - ) - } - } - - @Test - fun `open settings activity`() = runTest { - val shareLocationPresenter = createShareLocationPresenter() - fakePermissionsPresenter.givenState( - aPermissionsState( - permissions = PermissionsState.Permissions.NoneGranted, - shouldShowRationale = false, - ) - ) - fakeMessageComposerContext.apply { - composerMode = MessageComposerMode.Edit( - eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(), - content = "" - ) - } - - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - // Skip initial state - val initialState = awaitItem() - - initialState.eventSink(ShareLocationEvent.SwitchToMyLocationMode) - val dialogShownState = awaitItem() - - // Open settings - dialogShownState.eventSink(ShareLocationEvent.OpenAppSettings) - val settingsOpenedState = awaitItem() - - assertThat(settingsOpenedState.dialogState).isEqualTo(ShareLocationState.Dialog.None) - assertThat(fakeLocationActions.openSettingsInvocationsCount).isEqualTo(1) - } - } - - @Test - fun `application name is in state`() = runTest { - val shareLocationPresenter = createShareLocationPresenter() - moleculeFlow(RecompositionMode.Immediate) { - shareLocationPresenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.appName).isEqualTo("app name") + cancelAndIgnoreRemainingEvents() } } } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt new file mode 100644 index 0000000000..a3e221f77e --- /dev/null +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2024, 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.location.impl.share + +import androidx.activity.ComponentActivity +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState +import io.element.android.libraries.testtags.TestTags +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EnsureNeverCalled +import io.element.android.tests.testutils.EventsRecorder +import io.element.android.tests.testutils.clickOn +import io.element.android.tests.testutils.ensureCalledOnce +import io.element.android.tests.testutils.pressBack +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ShareLocationViewTest { + @get:Rule val rule = createAndroidComposeRule() + + @Test + fun `test back action`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setShareLocationView( + state = aShareLocationState( + eventSink = eventsRecorder + ), + navigateUp = callback, + ) + rule.pressBack() + } + } + + @Test + fun `test fab click`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.onNodeWithTag(TestTags.floatingActionButton.value).performClick() + eventsRecorder.assertSingle(ShareLocationEvent.StartTrackingUserLocation) + } + + @Test + fun `when permission denied is displayed user can open the settings`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied), + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_continue) + eventsRecorder.assertSingle(ShareLocationEvent.OpenAppSettings) + } + + @Test + fun `when permission denied is displayed user can close the dialog`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied), + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog) + } + + @Test + fun `when permission rationale is displayed user can request permissions`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale), + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_continue) + eventsRecorder.assertSingle(ShareLocationEvent.RequestPermissions) + } + + @Test + fun `when permission rationale is displayed user can close the dialog`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale), + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog) + } + + @Test + fun `when location service disabled is displayed user can open location settings`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled), + hasLocationPermission = true, + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_continue) + eventsRecorder.assertSingle(ShareLocationEvent.OpenLocationSettings) + } + + @Test + fun `when location service disabled is displayed user can close the dialog`() { + val eventsRecorder = EventsRecorder() + rule.setShareLocationView( + aShareLocationState( + dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled), + hasLocationPermission = true, + eventSink = eventsRecorder + ), + navigateUp = EnsureNeverCalled(), + ) + rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog) + } +} + +private fun AndroidComposeTestRule.setShareLocationView( + state: ShareLocationState, + navigateUp: () -> Unit = EnsureNeverCalled(), +) { + setContent { + // Simulate a LocalInspectionMode for MapLibreMap + CompositionLocalProvider(LocalInspectionMode provides true) { + ShareLocationView( + state = state, + navigateUp = navigateUp, + ) + } + } +} diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt index a49b887a42..b8a32e5912 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt @@ -13,8 +13,11 @@ import com.bumble.appyx.core.modality.BuildContext import com.google.common.truth.Truth.assertThat import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationEntryPoint +import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter +import io.element.android.libraries.dateformatter.test.FakeDateFormatter +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.node.TestParentNode @@ -32,21 +35,27 @@ class DefaultShowLocationEntryPointTest { ShowLocationNode( buildContext = buildContext, plugins = plugins, - presenterFactory = { location: Location, description: String? -> - ShowLocationPresenter( + presenterFactory = object : ShowLocationPresenter.Factory { + override fun create(mode: ShowLocationMode) = ShowLocationPresenter( + mode = mode, permissionsPresenterFactory = { FakePermissionsPresenter() }, locationActions = FakeLocationActions(), buildMeta = aBuildMeta(), - location = location, - description = description, + dateFormatter = FakeDateFormatter(), ) }, analyticsService = FakeAnalyticsService(), ) } val inputs = ShowLocationEntryPoint.Inputs( - location = Location(37.4219983, -122.084, 10f), - description = "My location", + mode = ShowLocationMode.Static( + location = Location(37.4219983, -122.084, 10f), + senderName = "Alice", + senderId = UserId("@alice:matrix.org"), + senderAvatarUrl = null, + timestamp = System.currentTimeMillis(), + assetType = null, + ), ) val result = entryPoint.createNode( parentNode = parentNode, diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index ebbad8e9d1..e1fe3691c0 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.test import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -66,9 +67,8 @@ class ShowLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isFalse() assertThat(initialState.isTrackMyLocation).isFalse() @@ -84,9 +84,8 @@ class ShowLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isFalse() assertThat(initialState.isTrackMyLocation).isFalse() @@ -97,9 +96,8 @@ class ShowLocationPresenterTest { fun `emits initial state with location permission`() = runTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() @@ -110,9 +108,8 @@ class ShowLocationPresenterTest { fun `emits initial state with partial location permission`() = runTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.SomeGranted)) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() @@ -121,9 +118,8 @@ class ShowLocationPresenterTest { @Test fun `uses action to share location`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() initialState.eventSink(ShowLocationEvents.Share(location)) @@ -135,9 +131,8 @@ class ShowLocationPresenterTest { fun `centers on user location`() = runTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() @@ -168,9 +163,8 @@ class ShowLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { // Skip initial state val initialState = awaitItem() @@ -198,10 +192,8 @@ class ShowLocationPresenterTest { shouldShowRationale = true, ) ) - - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { // Skip initial state val initialState = awaitItem() @@ -227,9 +219,8 @@ class ShowLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { // Skip initial state val initialState = awaitItem() @@ -258,9 +249,8 @@ class ShowLocationPresenterTest { ) ) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter().present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { // Skip initial state val initialState = awaitItem() @@ -291,9 +281,8 @@ class ShowLocationPresenterTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) fakeLocationActions.givenLocationEnabled(false) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter(locationActions = fakeLocationActions).present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.hasLocationPermission).isTrue() @@ -311,9 +300,8 @@ class ShowLocationPresenterTest { fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted)) fakeLocationActions.givenLocationEnabled(false) - moleculeFlow(RecompositionMode.Immediate) { - createShowLocationPresenter(locationActions = fakeLocationActions).present() - }.test { + val presenter = createShowLocationPresenter() + presenter.test { val initialState = awaitItem() initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) From fb775833c7ade300c691bf2ddf543326730af096 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 12:35:46 +0100 Subject: [PATCH 034/103] Code cleanup --- .../features/location/api/LocationKtTest.kt | 1 - .../impl/common/LocationConstraintsCheck.kt | 32 +++++++++---------- .../common/ui/LocationFloatingActionButton.kt | 2 -- .../impl/common/ui/LocationShareRow.kt | 8 ++--- .../impl/common/ui/MapBottomSheetScaffold.kt | 6 ++-- .../impl/share/LiveLocationDuration.kt | 4 +-- .../location/impl/share/ShareLocationEvent.kt | 2 +- .../impl/share/ShareLocationPresenter.kt | 8 ++--- .../location/impl/share/ShareLocationView.kt | 8 ++--- .../impl/show/ShowLocationPresenter.kt | 6 ++-- .../location/impl/show/ShowLocationView.kt | 2 +- .../src/main/res/drawable-night/pin_small.xml | 19 ----------- .../impl/src/main/res/drawable/pin_small.xml | 19 ----------- .../common/LocationConstraintsCheckTest.kt | 11 +++---- .../impl/share/ShareLocationPresenterTest.kt | 1 - .../impl/share/ShareLocationViewTest.kt | 3 +- .../impl/show/ShowLocationPresenterTest.kt | 2 +- .../messages/impl/MessagesFlowNode.kt | 1 - .../event/TimelineItemLocationView.kt | 4 --- .../TimelineItemContentMessageFactory.kt | 5 --- .../event/TimelineItemLocationContent.kt | 2 -- .../TimelineItemLocationContentProvider.kt | 2 -- .../components/avatar/internal/ImageAvatar.kt | 2 -- .../components/dialogs/ListDialog.kt | 1 - .../api/room/location/LiveLocationInfo.kt | 1 - .../api/timeline/item/event/EventContent.kt | 2 +- .../matrix/impl/room/location/AssetType.kt | 2 +- .../ui/components/AttachmentThumbnail.kt | 1 - 28 files changed, 44 insertions(+), 113 deletions(-) delete mode 100644 features/location/impl/src/main/res/drawable-night/pin_small.xml delete mode 100644 features/location/impl/src/main/res/drawable/pin_small.xml diff --git a/features/location/api/src/test/kotlin/io/element/android/features/location/api/LocationKtTest.kt b/features/location/api/src/test/kotlin/io/element/android/features/location/api/LocationKtTest.kt index b0f80e4fcf..74bb7fe953 100644 --- a/features/location/api/src/test/kotlin/io/element/android/features/location/api/LocationKtTest.kt +++ b/features/location/api/src/test/kotlin/io/element/android/features/location/api/LocationKtTest.kt @@ -79,4 +79,3 @@ internal class LocationKtTest { .isEqualTo("geo:1.0,2.0;u=3.0") } } - diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt index 51d57713c5..a0b0cd4734 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheck.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Element Creations Ltd. + * Copyright (c) 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -11,35 +11,35 @@ import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState -sealed interface LocationConstraintsCheckResult { - data object Success : LocationConstraintsCheckResult - data object PermissionRationale : LocationConstraintsCheckResult - data object PermissionDenied : LocationConstraintsCheckResult - data object LocationServiceDisabled : LocationConstraintsCheckResult +sealed interface LocationConstraintsCheck { + data object Success : LocationConstraintsCheck + data object PermissionRationale : LocationConstraintsCheck + data object PermissionDenied : LocationConstraintsCheck + data object LocationServiceDisabled : LocationConstraintsCheck } fun checkLocationConstraints( permissionsState: PermissionsState, locationActions: LocationActions, -): LocationConstraintsCheckResult { +): LocationConstraintsCheck { return when { permissionsState.isAnyGranted -> { if (locationActions.isLocationEnabled()) { - LocationConstraintsCheckResult.Success + LocationConstraintsCheck.Success } else { - LocationConstraintsCheckResult.LocationServiceDisabled + LocationConstraintsCheck.LocationServiceDisabled } } - permissionsState.shouldShowRationale -> LocationConstraintsCheckResult.PermissionRationale - else -> LocationConstraintsCheckResult.PermissionDenied + permissionsState.shouldShowRationale -> LocationConstraintsCheck.PermissionRationale + else -> LocationConstraintsCheck.PermissionDenied } } -fun LocationConstraintsCheckResult.toDialogState(): LocationConstraintsDialogState { +fun LocationConstraintsCheck.toDialogState(): LocationConstraintsDialogState { return when (this) { - LocationConstraintsCheckResult.Success -> LocationConstraintsDialogState.None - LocationConstraintsCheckResult.PermissionRationale -> LocationConstraintsDialogState.PermissionRationale - LocationConstraintsCheckResult.PermissionDenied -> LocationConstraintsDialogState.PermissionDenied - LocationConstraintsCheckResult.LocationServiceDisabled -> LocationConstraintsDialogState.LocationServiceDisabled + LocationConstraintsCheck.Success -> LocationConstraintsDialogState.None + LocationConstraintsCheck.PermissionRationale -> LocationConstraintsDialogState.PermissionRationale + LocationConstraintsCheck.PermissionDenied -> LocationConstraintsDialogState.PermissionDenied + LocationConstraintsCheck.LocationServiceDisabled -> LocationConstraintsDialogState.LocationServiceDisabled } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt index 99a4c7470f..28e3f1992e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationFloatingActionButton.kt @@ -10,8 +10,6 @@ package io.element.android.features.location.impl.common.ui import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.FloatingActionButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt index ec059b61b3..9e5e35b2ba 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt @@ -77,8 +77,8 @@ fun LocationShareRow( tint = ElementTheme.colors.iconAccentPrimary, modifier = Modifier.size(16.dp), ) - }else { - val icon = if(item.assetType == AssetType.PIN) CompoundIcons.LocationNavigator() else CompoundIcons.LocationNavigatorCentred() + } else { + val icon = if (item.assetType == AssetType.PIN) CompoundIcons.LocationNavigator() else CompoundIcons.LocationNavigatorCentred() Icon( imageVector = icon, contentDescription = null, @@ -122,7 +122,7 @@ internal fun LocationShareRowPreview() = ElementPreview { formattedTimestamp = "Shared 1 min ago", assetType = AssetType.SENDER, isLive = true, - location = Location(0.0,0.0) + location = Location(0.0, 0.0) ), onShareClick = {}, ) @@ -139,7 +139,7 @@ internal fun LocationShareRowPreview() = ElementPreview { assetType = AssetType.PIN, formattedTimestamp = "Shared 5 hours ago", isLive = false, - location = Location(0.0,0.0) + location = Location(0.0, 0.0) ), onShareClick = {}, ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt index 97ed6baa62..33726de6e8 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Element Creations Ltd. + * Copyright (c) 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -7,7 +7,6 @@ package io.element.android.features.location.impl.common.ui -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxWithConstraints @@ -37,7 +36,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -124,7 +122,7 @@ fun MapBottomSheetScaffold( ) { val ornamentOptions = mapOptions.ornamentOptions.copy(padding = sheetPadding) val mapOptions = mapOptions.copy(ornamentOptions = ornamentOptions) - Box{ + Box { MaplibreMap( options = mapOptions, baseStyle = BaseStyle.Uri(rememberTileStyleUrl()), diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt index 8763263d57..e4ecf331f6 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Element Creations Ltd. + * Copyright (c) 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -17,5 +17,5 @@ enum class LiveLocationDuration( ) { FifteenMinutes(15.minutes, "15 minutes"), OneHour(1.hours, "1 hour"), - EightHours(8.hours, "8 hours"); + EightHours(8.hours, "8 hours") } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt index b95e86084b..d9ebc8b5af 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationEvent.kt @@ -24,7 +24,7 @@ sealed interface ShareLocationEvent { data object StopTrackingUserLocation : ShareLocationEvent data object DismissDialog : ShareLocationEvent - data object RequestPermissions: ShareLocationEvent + data object RequestPermissions : ShareLocationEvent data object OpenAppSettings : ShareLocationEvent data object OpenLocationSettings : ShareLocationEvent } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 7ca8cbb7e3..56b7b073d9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -21,7 +21,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.Composer -import io.element.android.features.location.impl.common.LocationConstraintsCheckResult +import io.element.android.features.location.impl.common.LocationConstraintsCheck import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.checkLocationConstraints @@ -81,7 +81,7 @@ class ShareLocationPresenter( fun checkLocationConstraints() { val locationConstraints = checkLocationConstraints(permissionsState, locationActions) dialogState = Constraints(locationConstraints.toDialogState()) - trackUserPosition = locationConstraints is LocationConstraintsCheckResult.Success + trackUserPosition = locationConstraints is LocationConstraintsCheck.Success } LaunchedEffect(permissionsState.permissions) { checkLocationConstraints() } @@ -104,7 +104,7 @@ class ShareLocationPresenter( } ShareLocationEvent.ShowLiveLocationDurationPicker -> { val constraintsResult = checkLocationConstraints(permissionsState, locationActions) - dialogState = if (constraintsResult is LocationConstraintsCheckResult.Success) { + dialogState = if (constraintsResult is LocationConstraintsCheck.Success) { ShareLocationState.Dialog.LiveLocationDuration } else { Constraints(constraintsResult.toDialogState()) @@ -112,7 +112,7 @@ class ShareLocationPresenter( } is ShareLocationEvent.StartLiveLocationShare -> scope.launch { dialogState = ShareLocationState.Dialog.None - //room.startLiveLocationShare(event.duration.inWholeMilliseconds) + // room.startLiveLocationShare(event.duration.inWholeMilliseconds) } ShareLocationEvent.RequestPermissions -> { dialogState = ShareLocationState.Dialog.None diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index e5fa9d8c0c..f562647bc9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -8,13 +8,11 @@ package io.element.android.features.location.impl.share -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState @@ -22,8 +20,6 @@ import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -44,9 +40,7 @@ import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent -import io.element.android.libraries.designsystem.components.list.RadioButtonListItem import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.IconSource @@ -249,6 +243,7 @@ private fun LiveLocationDurationDialog( onSelectDuration: (Duration) -> Unit, onDismiss: () -> Unit, ) { + /* var selectedIndex by remember { mutableIntStateOf(0) } ListDialog( title = "Choose how long to share your live location.", @@ -268,6 +263,7 @@ private fun LiveLocationDurationDialog( ) } } + */ } @PreviewsDayNight diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index c48c2c27d2..01021b9972 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -19,8 +19,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import io.element.android.features.location.api.ShowLocationMode -import io.element.android.features.location.impl.common.LocationConstraintsCheckResult -import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState +import io.element.android.features.location.impl.common.LocationConstraintsCheck import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.actions.LocationActions import io.element.android.features.location.impl.common.checkLocationConstraints @@ -28,6 +27,7 @@ import io.element.android.features.location.impl.common.permissions.PermissionsE import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.features.location.impl.common.toDialogState +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta @@ -76,7 +76,7 @@ class ShowLocationPresenter( is ShowLocationEvents.TrackMyLocation -> { if (event.enabled) { val locationConstraints = checkLocationConstraints(permissionsState, locationActions) - isTrackMyLocation = locationConstraints is LocationConstraintsCheckResult.Success + isTrackMyLocation = locationConstraints is LocationConstraintsCheck.Success dialogState = locationConstraints.toDialogState() } else { isTrackMyLocation = false diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 3d3dc6f5c6..55fecf3e39 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -27,8 +27,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.location.api.ShowLocationMode -import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.MapDefaults +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton import io.element.android.features.location.impl.common.ui.LocationPinMarkers import io.element.android.features.location.impl.common.ui.LocationShareRow diff --git a/features/location/impl/src/main/res/drawable-night/pin_small.xml b/features/location/impl/src/main/res/drawable-night/pin_small.xml deleted file mode 100644 index 2e8a54b70e..0000000000 --- a/features/location/impl/src/main/res/drawable-night/pin_small.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - diff --git a/features/location/impl/src/main/res/drawable/pin_small.xml b/features/location/impl/src/main/res/drawable/pin_small.xml deleted file mode 100644 index 0e277a1ed2..0000000000 --- a/features/location/impl/src/main/res/drawable/pin_small.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt index 801d58e5da..c8e1f21a48 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/LocationConstraintsCheckTest.kt @@ -23,7 +23,7 @@ class LocationConstraintsCheckTest { val result = checkLocationConstraints(permissionsState, locationActions) - assertThat(result).isEqualTo(LocationConstraintsCheckResult.Success) + assertThat(result).isEqualTo(LocationConstraintsCheck.Success) } @Test @@ -35,7 +35,7 @@ class LocationConstraintsCheckTest { val result = checkLocationConstraints(permissionsState, locationActions) - assertThat(result).isEqualTo(LocationConstraintsCheckResult.Success) + assertThat(result).isEqualTo(LocationConstraintsCheck.Success) } @Test @@ -47,7 +47,7 @@ class LocationConstraintsCheckTest { val result = checkLocationConstraints(permissionsState, locationActions) - assertThat(result).isEqualTo(LocationConstraintsCheckResult.LocationServiceDisabled) + assertThat(result).isEqualTo(LocationConstraintsCheck.LocationServiceDisabled) } @Test @@ -60,7 +60,7 @@ class LocationConstraintsCheckTest { val result = checkLocationConstraints(permissionsState, locationActions) - assertThat(result).isEqualTo(LocationConstraintsCheckResult.PermissionRationale) + assertThat(result).isEqualTo(LocationConstraintsCheck.PermissionRationale) } @Test @@ -73,7 +73,6 @@ class LocationConstraintsCheckTest { val result = checkLocationConstraints(permissionsState, locationActions) - assertThat(result).isEqualTo(LocationConstraintsCheckResult.PermissionDenied) + assertThat(result).isEqualTo(LocationConstraintsCheck.PermissionDenied) } - } diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index b9311188d2..125d5036fe 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -37,7 +37,6 @@ 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.delay import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Rule diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt index a3e221f77e..317fbf8fed 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationViewTest.kt @@ -1,6 +1,5 @@ /* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2024, 2025 New Vector Ltd. + * Copyright (c) 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index e1fe3691c0..a875800672 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -15,11 +15,11 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.location.api.Location import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.aPermissionsState -import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsEvents import io.element.android.features.location.impl.common.permissions.PermissionsState +import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta 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 9ad7c48e36..38d0504258 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 @@ -75,7 +75,6 @@ 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.room.location.AssetType 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 diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt index b5c0152685..592b95a337 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt @@ -17,10 +17,6 @@ import androidx.compose.ui.unit.dp import io.element.android.features.location.api.StaticMapView import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContentProvider -import io.element.android.libraries.designsystem.components.PinVariant -import io.element.android.libraries.designsystem.components.avatar.Avatar -import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index 829c11df6e..723ab6feac 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -29,13 +29,9 @@ import io.element.android.features.messages.impl.utils.TextPillificationHelper import io.element.android.libraries.androidutils.filesize.FileSizeFormatter import io.element.android.libraries.androidutils.text.safeLinkify import io.element.android.libraries.core.mimetype.MimeTypes -import io.element.android.libraries.designsystem.components.PinVariant -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.core.EventId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkParser -import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -49,7 +45,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessag import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType -import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName import io.element.android.libraries.matrix.ui.messages.toHtmlDocument import io.element.android.libraries.mediaviewer.api.util.FileExtensionExtractor diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt index 74147c697f..fce44debd2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt @@ -27,7 +27,6 @@ data class TimelineItemLocationContent( val assetType: AssetType? = null, val mode: Mode, ) : TimelineItemEventContent { - val pinVariant = when (mode) { is Mode.Live -> { if (mode.isActive) { @@ -61,4 +60,3 @@ data class TimelineItemLocationContent( override val type: String = "TimelineItemLocationContent" } - diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt index 07ab392f1e..362e9b4cda 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContentProvider.kt @@ -11,9 +11,7 @@ package io.element.android.features.messages.impl.timeline.model.event import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails -import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.messages.reply.aProfileDetailsReady open class TimelineItemLocationContentProvider : PreviewParameterProvider { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt index e626e0f069..da57fbcbe1 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/internal/ImageAvatar.kt @@ -17,12 +17,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.Dp import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent -import coil3.request.ImageRequest import io.element.android.libraries.designsystem.components.avatar.AvatarData import timber.log.Timber diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt index ffaab12eba..91c058a0e4 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt @@ -9,7 +9,6 @@ package io.element.android.libraries.designsystem.components.dialogs import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt index 50b5a0ec82..a04ef2dfb9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/location/LiveLocationInfo.kt @@ -12,4 +12,3 @@ data class LiveLocationInfo( val geoUri: String, val timestamp: Long, ) - diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index e7b61e8dd6..95d4327c07 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -111,7 +111,7 @@ data class LiveLocationContent( val timeout: Long, val assetType: AssetType?, val locations: List, -): EventContent +) : EventContent data object LegacyCallInviteContent : EventContent diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt index a88a2524c2..5f8fa70f59 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/location/AssetType.kt @@ -17,7 +17,7 @@ fun AssetType.into(): RustAssetType = when (this) { AssetType.UNKNOWN -> RustAssetType.UNKNOWN } -fun RustAssetType.into(): AssetType = when(this){ +fun RustAssetType.into(): AssetType = when (this) { RustAssetType.SENDER -> AssetType.SENDER RustAssetType.PIN -> AssetType.PIN RustAssetType.UNKNOWN -> AssetType.UNKNOWN diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt index 9b55c85524..e5149682e3 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt @@ -11,7 +11,6 @@ package io.element.android.libraries.matrix.ui.components import android.os.Parcelable import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme From 089b0cd84771df747a2724cd7cb842347a4869e8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 12:40:10 +0100 Subject: [PATCH 035/103] Disable live location sharing for now (nothing done) --- .../features/location/impl/share/ShareLocationPresenter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 56b7b073d9..ec5414de77 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -126,7 +126,7 @@ class ShareLocationPresenter( dialogState = dialogState, trackUserLocation = trackUserPosition, hasLocationPermission = permissionsState.isAnyGranted, - canShareLiveLocation = isLiveLocationSharingEnabled, + canShareLiveLocation = false, appName = appName, eventSink = ::handleEvent, ) From 30919dcff45f91c6e272e535c2f992a3fca8af09 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 12:47:52 +0100 Subject: [PATCH 036/103] Rename ShowLocationEvents -> ShowLocationEvent --- ...LocationEvents.kt => ShowLocationEvent.kt} | 14 +++++----- .../impl/show/ShowLocationPresenter.kt | 14 +++++----- .../location/impl/show/ShowLocationState.kt | 2 +- .../impl/show/ShowLocationStateProvider.kt | 2 +- .../location/impl/show/ShowLocationView.kt | 16 +++++------ .../impl/show/ShowLocationPresenterTest.kt | 28 +++++++++---------- .../impl/show/ShowLocationViewTest.kt | 26 ++++++++--------- 7 files changed, 51 insertions(+), 51 deletions(-) rename features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/{ShowLocationEvents.kt => ShowLocationEvent.kt} (64%) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvent.kt similarity index 64% rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvent.kt index 52ff87b393..6a3e3521e0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvents.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationEvent.kt @@ -10,11 +10,11 @@ package io.element.android.features.location.impl.show import io.element.android.features.location.api.Location -sealed interface ShowLocationEvents { - data class Share(val location: Location) : ShowLocationEvents - data class TrackMyLocation(val enabled: Boolean) : ShowLocationEvents - data object DismissDialog : ShowLocationEvents - data object RequestPermissions : ShowLocationEvents - data object OpenAppSettings : ShowLocationEvents - data object OpenLocationSettings : ShowLocationEvents +sealed interface ShowLocationEvent { + data class Share(val location: Location) : ShowLocationEvent + data class TrackMyLocation(val enabled: Boolean) : ShowLocationEvent + data object DismissDialog : ShowLocationEvent + data object RequestPermissions : ShowLocationEvent + data object OpenAppSettings : ShowLocationEvent + data object OpenLocationSettings : ShowLocationEvent } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 01021b9972..d74d2f36e1 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -68,12 +68,12 @@ class ShowLocationPresenter( } } - fun handleEvent(event: ShowLocationEvents) { + fun handleEvent(event: ShowLocationEvent) { when (event) { - is ShowLocationEvents.Share -> { + is ShowLocationEvent.Share -> { locationActions.share(event.location, null) } - is ShowLocationEvents.TrackMyLocation -> { + is ShowLocationEvent.TrackMyLocation -> { if (event.enabled) { val locationConstraints = checkLocationConstraints(permissionsState, locationActions) isTrackMyLocation = locationConstraints is LocationConstraintsCheck.Success @@ -82,16 +82,16 @@ class ShowLocationPresenter( isTrackMyLocation = false } } - ShowLocationEvents.DismissDialog -> dialogState = LocationConstraintsDialogState.None - ShowLocationEvents.OpenAppSettings -> { + ShowLocationEvent.DismissDialog -> dialogState = LocationConstraintsDialogState.None + ShowLocationEvent.OpenAppSettings -> { locationActions.openAppSettings() dialogState = LocationConstraintsDialogState.None } - ShowLocationEvents.OpenLocationSettings -> { + ShowLocationEvent.OpenLocationSettings -> { locationActions.openLocationSettings() dialogState = LocationConstraintsDialogState.None } - ShowLocationEvents.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) + ShowLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions) } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 3a8fcf51de..85d79f1192 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -24,7 +24,7 @@ data class ShowLocationState( val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, val appName: String, - val eventSink: (ShowLocationEvents) -> Unit, + val eventSink: (ShowLocationEvent) -> Unit, ) { val isSheetDraggable = locationShares.any { item -> item.isLive } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 6880ed1bf5..7289ec000c 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -53,7 +53,7 @@ fun aShowLocationState( hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, appName: String = APP_NAME, - eventSink: (ShowLocationEvents) -> Unit = {}, + eventSink: (ShowLocationEvent) -> Unit = {}, ): ShowLocationState { val effectiveMarkers = markers ?: when (mode) { is ShowLocationMode.Static -> listOf( diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index 55fecf3e39..fdeb027b1e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -57,10 +57,10 @@ fun ShowLocationView( LocationConstraintsDialog( state = state.dialogState, appName = state.appName, - onRequestPermissions = { state.eventSink(ShowLocationEvents.RequestPermissions) }, - onOpenAppSettings = { state.eventSink(ShowLocationEvents.OpenAppSettings) }, - onOpenLocationSettings = { state.eventSink(ShowLocationEvents.OpenLocationSettings) }, - onDismiss = { state.eventSink(ShowLocationEvents.DismissDialog) }, + onRequestPermissions = { state.eventSink(ShowLocationEvent.RequestPermissions) }, + onOpenAppSettings = { state.eventSink(ShowLocationEvent.OpenAppSettings) }, + onOpenLocationSettings = { state.eventSink(ShowLocationEvent.OpenLocationSettings) }, + onDismiss = { state.eventSink(ShowLocationEvent.DismissDialog) }, ) val initialPosition = when (val mode = state.mode) { @@ -74,7 +74,7 @@ fun ShowLocationView( val userLocationState = rememberUserLocationState(state.hasLocationPermission) LaunchedEffect(cameraState.isCameraMoving) { if (cameraState.moveReason == CameraMoveReason.GESTURE) { - state.eventSink(ShowLocationEvents.TrackMyLocation(false)) + state.eventSink(ShowLocationEvent.TrackMyLocation(false)) } } @@ -120,9 +120,9 @@ fun ShowLocationView( state.locationShares.forEach { locationShare -> LocationShareRow( item = locationShare, - onShareClick = { state.eventSink(ShowLocationEvents.Share(locationShare.location)) }, + onShareClick = { state.eventSink(ShowLocationEvent.Share(locationShare.location)) }, modifier = Modifier.clickable { - state.eventSink(ShowLocationEvents.TrackMyLocation(false)) + state.eventSink(ShowLocationEvent.TrackMyLocation(false)) val position = CameraPosition( padding = sheetPaddings, target = Position(locationShare.location.lon, locationShare.location.lat), @@ -146,7 +146,7 @@ fun ShowLocationView( overlayContent = { LocationFloatingActionButton( isMapCenteredOnUser = state.isTrackMyLocation, - onClick = { state.eventSink(ShowLocationEvents.TrackMyLocation(true)) }, + onClick = { state.eventSink(ShowLocationEvent.TrackMyLocation(true)) }, modifier = Modifier .align(Alignment.TopEnd) .padding(all = 16.dp), diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index a875800672..8a29f0463d 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -121,7 +121,7 @@ class ShowLocationPresenterTest { val presenter = createShowLocationPresenter() presenter.test { val initialState = awaitItem() - initialState.eventSink(ShowLocationEvents.Share(location)) + initialState.eventSink(ShowLocationEvent.Share(location)) assertThat(fakeLocationActions.sharedLocation).isEqualTo(location) } @@ -137,7 +137,7 @@ class ShowLocationPresenterTest { assertThat(initialState.hasLocationPermission).isTrue() assertThat(initialState.isTrackMyLocation).isFalse() - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val trackMyLocationState = awaitItem() delay(1) @@ -146,7 +146,7 @@ class ShowLocationPresenterTest { assertThat(trackMyLocationState.isTrackMyLocation).isTrue() // Swipe the map to switch mode - initialState.eventSink(ShowLocationEvents.TrackMyLocation(false)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(false)) val trackLocationDisabledState = awaitItem() assertThat(trackLocationDisabledState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(trackLocationDisabledState.isTrackMyLocation).isFalse() @@ -169,14 +169,14 @@ class ShowLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val trackLocationState = awaitItem() assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionRationale) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - initialState.eventSink(ShowLocationEvents.DismissDialog) + initialState.eventSink(ShowLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() assertThat(dialogDismissedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(dialogDismissedState.isTrackMyLocation).isFalse() @@ -198,14 +198,14 @@ class ShowLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val trackLocationState = awaitItem() assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionRationale) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() // Continue the dialog sends permission request to the permissions presenter - trackLocationState.eventSink(ShowLocationEvents.RequestPermissions) + trackLocationState.eventSink(ShowLocationEvent.RequestPermissions) assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions) } } @@ -225,14 +225,14 @@ class ShowLocationPresenterTest { val initialState = awaitItem() // Click on the button to switch mode - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val trackLocationState = awaitItem() assertThat(trackLocationState.dialogState).isEqualTo(LocationConstraintsDialogState.PermissionDenied) assertThat(trackLocationState.isTrackMyLocation).isFalse() assertThat(trackLocationState.hasLocationPermission).isFalse() // Dismiss the dialog - initialState.eventSink(ShowLocationEvents.DismissDialog) + initialState.eventSink(ShowLocationEvent.DismissDialog) val dialogDismissedState = awaitItem() assertThat(dialogDismissedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) assertThat(dialogDismissedState.isTrackMyLocation).isFalse() @@ -254,11 +254,11 @@ class ShowLocationPresenterTest { // Skip initial state val initialState = awaitItem() - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val dialogShownState = awaitItem() // Open settings - dialogShownState.eventSink(ShowLocationEvents.OpenAppSettings) + dialogShownState.eventSink(ShowLocationEvent.OpenAppSettings) val settingsOpenedState = awaitItem() assertThat(settingsOpenedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) @@ -287,7 +287,7 @@ class ShowLocationPresenterTest { assertThat(initialState.hasLocationPermission).isTrue() // Try to track location when location services are disabled - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val dialogShownState = awaitItem() assertThat(dialogShownState.dialogState).isEqualTo(LocationConstraintsDialogState.LocationServiceDisabled) @@ -304,12 +304,12 @@ class ShowLocationPresenterTest { presenter.test { val initialState = awaitItem() - initialState.eventSink(ShowLocationEvents.TrackMyLocation(true)) + initialState.eventSink(ShowLocationEvent.TrackMyLocation(true)) val dialogShownState = awaitItem() assertThat(dialogShownState.dialogState).isEqualTo(LocationConstraintsDialogState.LocationServiceDisabled) // Open location settings - dialogShownState.eventSink(ShowLocationEvents.OpenLocationSettings) + dialogShownState.eventSink(ShowLocationEvent.OpenLocationSettings) val settingsOpenedState = awaitItem() assertThat(settingsOpenedState.dialogState).isEqualTo(LocationConstraintsDialogState.None) diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt index a70d3441c4..fecbbdbf89 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationViewTest.kt @@ -37,7 +37,7 @@ class ShowLocationViewTest { @Test fun `test back action`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) ensureCalledOnce { callback -> rule.setShowLocationView( state = aShowLocationState( @@ -51,7 +51,7 @@ class ShowLocationViewTest { @Test fun `test share action`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( eventSink = eventsRecorder @@ -61,12 +61,12 @@ class ShowLocationViewTest { val shareContentDescription = rule.activity.getString(CommonStrings.action_share) rule.onNodeWithContentDescription(shareContentDescription).performClick() // The default aStaticLocationMode uses Location(1.23, 2.34, 4f) - eventsRecorder.assertSingle(ShowLocationEvents.Share(Location(1.23, 2.34, 4f))) + eventsRecorder.assertSingle(ShowLocationEvent.Share(Location(1.23, 2.34, 4f))) } @Test fun `test fab click`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( eventSink = eventsRecorder @@ -74,12 +74,12 @@ class ShowLocationViewTest { onBackClick = EnsureNeverCalled(), ) rule.onNodeWithTag(TestTags.floatingActionButton.value).performClick() - eventsRecorder.assertSingle(ShowLocationEvents.TrackMyLocation(true)) + eventsRecorder.assertSingle(ShowLocationEvent.TrackMyLocation(true)) } @Test fun `when permission denied is displayed user can open the settings`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( constraintsDialogState = LocationConstraintsDialogState.PermissionDenied, @@ -88,12 +88,12 @@ class ShowLocationViewTest { onBackClick = EnsureNeverCalled(), ) rule.clickOn(CommonStrings.action_continue) - eventsRecorder.assertSingle(ShowLocationEvents.OpenAppSettings) + eventsRecorder.assertSingle(ShowLocationEvent.OpenAppSettings) } @Test fun `when permission denied is displayed user can close the dialog`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( constraintsDialogState = LocationConstraintsDialogState.PermissionDenied, @@ -102,12 +102,12 @@ class ShowLocationViewTest { onBackClick = EnsureNeverCalled(), ) rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(ShowLocationEvents.DismissDialog) + eventsRecorder.assertSingle(ShowLocationEvent.DismissDialog) } @Test fun `when permission rationale is displayed user can request permissions`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( constraintsDialogState = LocationConstraintsDialogState.PermissionRationale, @@ -116,12 +116,12 @@ class ShowLocationViewTest { onBackClick = EnsureNeverCalled(), ) rule.clickOn(CommonStrings.action_continue) - eventsRecorder.assertSingle(ShowLocationEvents.RequestPermissions) + eventsRecorder.assertSingle(ShowLocationEvent.RequestPermissions) } @Test fun `when permission rationale is displayed user can close the dialog`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setShowLocationView( aShowLocationState( constraintsDialogState = LocationConstraintsDialogState.PermissionRationale, @@ -130,7 +130,7 @@ class ShowLocationViewTest { onBackClick = EnsureNeverCalled(), ) rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(ShowLocationEvents.DismissDialog) + eventsRecorder.assertSingle(ShowLocationEvent.DismissDialog) } } From cdc773dab101b962321d78e105aa8c4c1387d6f9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 15:58:27 +0100 Subject: [PATCH 037/103] Remove hardcoded string --- .../location/impl/common/ui/LocationConstraintsDialog.kt | 2 +- libraries/ui-strings/src/main/res/values/localazy.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt index d42a551254..1ae4fa2182 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt @@ -45,7 +45,7 @@ fun LocationConstraintsDialog( cancelText = stringResource(CommonStrings.action_cancel), ) LocationConstraintsDialogState.LocationServiceDisabled -> ConfirmationDialog( - content = "Please enable your GPS to access location-based features.", + content = stringResource(CommonStrings.error_location_service_disabled_android), onSubmitClick = onOpenLocationSettings, onDismiss = onDismiss, submitText = stringResource(CommonStrings.action_continue), diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index d655532e6c..0aa2b29f2e 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -438,6 +438,7 @@ Are you sure you want to continue?" "%1$s could not access your location. Please try again later." "Failed to upload your voice message." "The room no longer exists or the invite is no longer valid." + "Please enable your GPS to access location-based features." "Message not found" "%1$s does not have permission to access your location. You can enable access in Settings." "%1$s does not have permission to access your location. Enable access below." From 02b3c61edc5ef06269ab7cbcdc1f5e9ef1f89eb2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 12 Mar 2026 21:12:52 +0100 Subject: [PATCH 038/103] Fix quality! --- .../impl/common/ui/LocationConstraintsDialog.kt | 16 +++++++++------- .../impl/common/ui/MapBottomSheetScaffold.kt | 7 ++++--- .../location/impl/common/ui/UserLocationPuck.kt | 2 ++ .../impl/share/ShareLocationPresenter.kt | 2 +- .../location/impl/share/ShareLocationView.kt | 14 +++++++++++--- .../impl/show/ShowLocationStateProvider.kt | 2 +- .../model/event/TimelineItemLocationContent.kt | 3 +-- .../impl/src/main/res/values/localazy.xml | 2 +- .../networkmonitor/impl/DefaultNetworkMonitor.kt | 5 ++++- .../designsystem/components/LocationPin.kt | 2 ++ .../designsystem/components/avatar/AvatarSize.kt | 2 +- 11 files changed, 37 insertions(+), 20 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt index 1ae4fa2182..188f8129f8 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt @@ -8,17 +8,11 @@ package io.element.android.features.location.impl.common.ui import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.ui.res.stringResource import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.ui.strings.CommonStrings -sealed interface LocationConstraintsDialogState { - data object None : LocationConstraintsDialogState - data object PermissionRationale : LocationConstraintsDialogState - data object PermissionDenied : LocationConstraintsDialogState - data object LocationServiceDisabled : LocationConstraintsDialogState -} - @Composable fun LocationConstraintsDialog( state: LocationConstraintsDialogState, @@ -53,3 +47,11 @@ fun LocationConstraintsDialog( ) } } + +@Immutable +sealed interface LocationConstraintsDialogState { + data object None : LocationConstraintsDialogState + data object PermissionRationale : LocationConstraintsDialogState + data object PermissionDenied : LocationConstraintsDialogState + data object LocationServiceDisabled : LocationConstraintsDialogState +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt index 33726de6e8..09c5067e1a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -60,15 +60,16 @@ import kotlin.math.roundToInt * - Updating camera position padding based on sheet height * - Rendering the MaplibreMap with proper ornament positioning * - * @param cameraState The camera state for the map - * @param topBar The top app bar content - * @param sheetContent The content to display in the bottom sheet * @param modifier Modifier for the root layout * @param scaffoldState State for the bottom sheet scaffold + * @param cameraState The camera state for the map + * @param mapOptions The options to configure the map * @param sheetPeekHeight The height of the sheet when collapsed * @param sheetDragHandle Optional drag handle for the sheet * @param sheetSwipeEnabled Whether the sheet can be swiped + * @param topBar The top app bar content * @param snackbarHost The snackbar host content + * @param sheetContent The content to display in the bottom sheet * @param mapContent The content inside the MaplibreMap (layers, location pucks, etc.) * @param overlayContent Content to overlay on top of the map (FAB, pin icons, etc.) */ diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt index f014debe08..8b89f77be4 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt @@ -7,6 +7,7 @@ package io.element.android.features.location.impl.common.ui +import android.annotation.SuppressLint import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.unit.dp @@ -63,6 +64,7 @@ fun UserLocationPuck( } } +@SuppressLint("MissingPermission") @Composable fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState { val isPreview = LocalInspectionMode.current diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index ec5414de77..56b7b073d9 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -126,7 +126,7 @@ class ShareLocationPresenter( dialogState = dialogState, trackUserLocation = trackUserPosition, hasLocationPermission = permissionsState.isAnyGranted, - canShareLiveLocation = false, + canShareLiveLocation = isLiveLocationSharingEnabled, appName = appName, eventSink = ::handleEvent, ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index f562647bc9..ecb4cf9dd4 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -8,11 +8,13 @@ package io.element.android.features.location.impl.share +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetValue import androidx.compose.material3.rememberBottomSheetScaffoldState @@ -20,9 +22,12 @@ import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -36,11 +41,14 @@ import io.element.android.features.location.impl.common.ui.LocationFloatingActio import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold import io.element.android.features.location.impl.common.ui.UserLocationPuck import io.element.android.features.location.impl.common.ui.rememberUserLocationState +import io.element.android.libraries.androidutils.system.toast import io.element.android.libraries.designsystem.components.LocationPin import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.dialogs.ListDialog import io.element.android.libraries.designsystem.components.list.ListItemContent +import io.element.android.libraries.designsystem.components.list.RadioButtonListItem import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.IconSource @@ -62,6 +70,7 @@ fun ShareLocationView( navigateUp: () -> Unit, modifier: Modifier = Modifier, ) { + val context = LocalContext.current when (val dialogState = state.dialogState) { ShareLocationState.Dialog.None -> Unit is ShareLocationState.Dialog.Constraints -> LocationConstraintsDialog( @@ -75,6 +84,7 @@ fun ShareLocationView( ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog( onSelectDuration = { duration -> state.eventSink(ShareLocationEvent.StartLiveLocationShare(duration)) + context.toast("Not implemented yet!") navigateUp() }, onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, @@ -129,7 +139,7 @@ fun ShareLocationView( .padding(sheetPadding) ) { val variant = if (state.trackUserLocation) { - PinVariant.UserLocation(isLive = false, avatarData = state.currentUser.getAvatarData(AvatarSize.SelectedUser)) + PinVariant.UserLocation(isLive = false, avatarData = state.currentUser.getAvatarData(AvatarSize.LocationPin)) } else { PinVariant.PinnedLocation } @@ -243,7 +253,6 @@ private fun LiveLocationDurationDialog( onSelectDuration: (Duration) -> Unit, onDismiss: () -> Unit, ) { - /* var selectedIndex by remember { mutableIntStateOf(0) } ListDialog( title = "Choose how long to share your live location.", @@ -263,7 +272,6 @@ private fun LiveLocationDurationDialog( ) } } - */ } @PreviewsDayNight diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 7289ec000c..9bbd818f1a 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -68,7 +68,7 @@ fun aShowLocationState( id = mode.senderId.value, name = mode.senderName, url = mode.senderAvatarUrl, - size = AvatarSize.UserListItem, + size = AvatarSize.LocationPin, ), isLive = true, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt index fce44debd2..aa9fb6b71e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt @@ -49,8 +49,7 @@ data class TimelineItemLocationContent( senderId.value, name = senderProfile.getDisplayName(), url = senderProfile.getAvatarUrl(), - // Size is irrelevant as the PinMarker will override anyway. - size = AvatarSize.TimelineSender + size = AvatarSize.LocationPin ) sealed interface Mode { diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index e8f4d4e6e5..f5629f5e2d 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -35,7 +35,7 @@ "Record video" "Attachment" "Photo & Video Library" - "Location" + "Share location" "Poll" "Text Formatting" "Message history is currently unavailable." diff --git a/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt b/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt index 949db720ce..7cffa057bc 100644 --- a/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt +++ b/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt @@ -15,6 +15,7 @@ import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest +import android.os.Build import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn @@ -83,7 +84,9 @@ class DefaultNetworkMonitor( if (network.networkHandle == connectivityManager.activeNetwork?.networkHandle) { // If the network doesn't have the NET_CAPABILITY_VALIDATED capability, it means that the network is not able to reach the internet // (according to Google), which is a common case in air-gapped environments. - isInAirGappedEnvironment.value = !networkCapabilities.capabilities.contains(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + isInAirGappedEnvironment.value = !networkCapabilities.capabilities.contains(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + } } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index 9fc0d1d27e..af8e29d518 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -60,6 +61,7 @@ private val STROKE_WIDTH = 1.dp /** * Variants of location pin markers. */ +@Immutable sealed interface PinVariant { data class UserLocation( val avatarData: AvatarData, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 8407445394..cd29773a5b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -75,6 +75,6 @@ enum class AvatarSize(val dp: Dp) { SpaceMember(24.dp), LeaveSpaceRoom(32.dp), SelectParentSpace(32.dp), - AccountItem(32.dp), + LocationPin(32.dp) } From 461b1c0e525b82f506352053b06b6fc839e576f6 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 12 Mar 2026 20:37:13 +0000 Subject: [PATCH 039/103] Update screenshots --- ...ures.location.impl.common.ui_LocationShareRow_Day_0_en.png | 3 +++ ...es.location.impl.common.ui_LocationShareRow_Night_0_en.png | 3 +++ .../features.location.impl.send_SendLocationView_Day_0_en.png | 3 --- .../features.location.impl.send_SendLocationView_Day_1_en.png | 3 --- .../features.location.impl.send_SendLocationView_Day_2_en.png | 3 --- .../features.location.impl.send_SendLocationView_Day_3_en.png | 3 --- .../features.location.impl.send_SendLocationView_Day_4_en.png | 3 --- ...eatures.location.impl.send_SendLocationView_Night_0_en.png | 3 --- ...eatures.location.impl.send_SendLocationView_Night_1_en.png | 3 --- ...eatures.location.impl.send_SendLocationView_Night_2_en.png | 3 --- ...eatures.location.impl.send_SendLocationView_Night_3_en.png | 3 --- ...eatures.location.impl.send_SendLocationView_Night_4_en.png | 3 --- ...eatures.location.impl.share_ShareLocationView_Day_0_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_1_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_2_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_3_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_4_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_5_en.png | 3 +++ ...eatures.location.impl.share_ShareLocationView_Day_6_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_0_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_1_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_2_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_3_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_4_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_5_en.png | 3 +++ ...tures.location.impl.share_ShareLocationView_Night_6_en.png | 3 +++ .../features.location.impl.show_ShowLocationView_Day_0_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_1_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_2_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_3_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_4_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_5_en.png | 4 ++-- .../features.location.impl.show_ShowLocationView_Day_6_en.png | 3 --- .../features.location.impl.show_ShowLocationView_Day_7_en.png | 3 --- ...eatures.location.impl.show_ShowLocationView_Night_0_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_1_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_2_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_3_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_4_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_5_en.png | 4 ++-- ...eatures.location.impl.show_ShowLocationView_Night_6_en.png | 3 --- ...eatures.location.impl.show_ShowLocationView_Night_7_en.png | 3 --- ...pl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en.png | 4 ++-- ....messagecomposer_AttachmentSourcePickerMenu_Night_0_en.png | 4 ++-- ...ine.components.event_TimelineItemLocationView_Day_1_en.png | 4 ++-- ...ine.components.event_TimelineItemLocationView_Day_2_en.png | 3 +++ ...e.components.event_TimelineItemLocationView_Night_1_en.png | 4 ++-- ...e.components.event_TimelineItemLocationView_Night_2_en.png | 3 +++ ...line.components_TimelineItemEventRowWithReply_Day_8_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_8_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_10_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_11_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_12_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_13_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_14_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_15_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_16_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_17_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_18_en.png | 3 +++ ...atures.messages.impl.timeline_TimelineView_Night_10_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_11_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_12_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_13_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_14_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_15_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_16_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_17_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_18_en.png | 3 +++ .../images/features.messages.impl_MessagesView_Day_1_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_1_en.png | 4 ++-- ...libraries.designsystem.components_LocationPin_Day_0_en.png | 3 +++ ...braries.designsystem.components_LocationPin_Night_0_en.png | 3 +++ .../libraries.designsystem.components_PinIcon_Day_0_en.png | 3 --- .../libraries.designsystem.components_PinIcon_Night_0_en.png | 3 --- ...ries.matrix.ui.components_AttachmentThumbnail_Day_6_en.png | 4 ++-- ...es.matrix.ui.components_AttachmentThumbnail_Night_6_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_8_en.png | 4 ++-- 82 files changed, 154 insertions(+), 136 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Day_0_en.png new file mode 100644 index 0000000000..e48b3cd8ab --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2550638ee12b4181cea31caff0b5838a9cdb3a180c01d1188bc7c2726051b863 +size 16578 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Night_0_en.png new file mode 100644 index 0000000000..0f17f6d6a1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.common.ui_LocationShareRow_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c880e4d01495868b3f0689d20d3cbf2050d6261be936421343bc1ac210aabeec +size 15959 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_0_en.png deleted file mode 100644 index 7b7a97ff45..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95a8d94f223cdb1f45fb43406688c7ae103a0e6c8cead84c7726795c553a3b54 -size 19773 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_1_en.png deleted file mode 100644 index 3a820c29a3..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0cf81beb22fca6641de9e08d69da0b6f2ed1e2593296987ac7c052c89010ee75 -size 35449 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_2_en.png deleted file mode 100644 index 6bb166ec80..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0281adefc90c5ec6a9788a142bca2bc486f1957e943791bb61c1e20e707ab0a7 -size 33926 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_3_en.png deleted file mode 100644 index 7b7a97ff45..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95a8d94f223cdb1f45fb43406688c7ae103a0e6c8cead84c7726795c553a3b54 -size 19773 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_4_en.png deleted file mode 100644 index 07827e9681..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Day_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6f357222c421d6f02414f3dd9d39c13cfceb36f3f4c6740b91cf18c75eace6e -size 18894 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_0_en.png deleted file mode 100644 index f1e4389d7a..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ece0a2814e93bf971c2bfd5309cd239d98795d8ae72041c0a48f0f304250a017 -size 19325 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_1_en.png deleted file mode 100644 index 11d4c7dd65..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:982df0a262833543c2d4cd56059e48e9020f3bf5b00843acec5b92066dd6ffb3 -size 33522 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_2_en.png deleted file mode 100644 index 97d474cf5a..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d05adff48c9c6dff7178c556d746f8729e45cb100d074f3bb6a2d783211612a -size 32108 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_3_en.png deleted file mode 100644 index f1e4389d7a..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ece0a2814e93bf971c2bfd5309cd239d98795d8ae72041c0a48f0f304250a017 -size 19325 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_4_en.png deleted file mode 100644 index 2ccb40dc97..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.send_SendLocationView_Night_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d7578366c6b02b2afe5899195138318bcdda1c408f61740b5fba9084f618a2a -size 18491 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_0_en.png new file mode 100644 index 0000000000..898a010ddf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db105243ef507c209c756015cf41a23150259cbe7ab3be6d233590fa9257b0e5 +size 20528 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_1_en.png new file mode 100644 index 0000000000..8957a012f2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d950639a9cc9961210b449e5c975b6f6bc890a47f4977eeaaa19b837458f66e +size 36475 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_2_en.png new file mode 100644 index 0000000000..bf25a07679 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a52d39cb27572c49ab64b1534ead353687d83870b5d5cfe7158859925b4717f3 +size 34926 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_3_en.png new file mode 100644 index 0000000000..3f99f935c9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccb0deee31506379cfa76f8d39d37639b6b1f03d7eb2e7d5e8c6ceff300b1978 +size 30397 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_4_en.png new file mode 100644 index 0000000000..898a010ddf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db105243ef507c209c756015cf41a23150259cbe7ab3be6d233590fa9257b0e5 +size 20528 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png new file mode 100644 index 0000000000..69aea3df2a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ba1418b5d42a56db47e7cc574cedb886c75d9cf22828341bd954a4f1845670e +size 17925 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_6_en.png new file mode 100644 index 0000000000..cce7a48382 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a97492422d54a6d6666c1ade693dc9b63bc9ca07c17d6c1f787c081984c09f68 +size 42470 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_0_en.png new file mode 100644 index 0000000000..dbd4836467 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3260d344a065f1710aff1450dbdaaa0bd1fbd963d5304167124d845c46be433 +size 19903 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_1_en.png new file mode 100644 index 0000000000..bf0e1594e1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:001bcd1755e837c0c05e493f964ee5c71fba81e811bdaf91effba257743bdacb +size 34836 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_2_en.png new file mode 100644 index 0000000000..11be8ba550 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38d253d8b3aa1c4599aa6b6f5982b7ef0c87ea7346aba13054a7891197b7c000 +size 33268 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_3_en.png new file mode 100644 index 0000000000..2c8c53dc1e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8901e7adb15ff01e9c696729f1abc52c5fc8666bca030f449f8caf5a22615f53 +size 29196 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_4_en.png new file mode 100644 index 0000000000..dbd4836467 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3260d344a065f1710aff1450dbdaaa0bd1fbd963d5304167124d845c46be433 +size 19903 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png new file mode 100644 index 0000000000..060f25819e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d786937d790e13b53a5de8ae3321e5aa8744a979a3a99ecc36def6b7dbf6cf60 +size 17237 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_6_en.png new file mode 100644 index 0000000000..541b2a97e1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:038e12f3caeef6ac8d5389b7cdc68138e089dcac335d0a5904adc55c9bcb7b1c +size 40642 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_0_en.png index a7e98b868f..46226555db 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c0d1a04c5a3096363f636da1d3226c4242936c2430f58a8d08af1b02c5d6808 -size 10890 +oid sha256:cdf7b194a075902ab9434e272865293535ef39370fbb9cb172b3cf8774850c73 +size 19104 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_1_en.png index d1664bb47d..ff0295d9ac 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83a49b16c632b680d5c6cd09043c4ca85fdbe8844d519d59377015f4d5657f1f -size 29457 +oid sha256:37ccae030071cc4801538dc5c753a6148ce7e465442edcc89877353b7f5675cb +size 37572 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_2_en.png index 02b18b4992..6f440d71d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c25ef1a184356bb6f7b751bb32abfa6963bf2a1bb4f5f9cdc090d1e573ce04e6 -size 27985 +oid sha256:5f57485d56fd4d02731f797762d931c4d738c8693539da612e33403693cd4b08 +size 35976 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_3_en.png index a7e98b868f..964ad077b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c0d1a04c5a3096363f636da1d3226c4242936c2430f58a8d08af1b02c5d6808 -size 10890 +oid sha256:c882f3f9ed18a64ecfa253284bf1dbdad5d38f524258b6463521d5185c1c32a7 +size 31530 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_4_en.png index c8400f7ca7..46226555db 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:651aa76c0a9b6845037c827728d6faf38864135d5a1a421f1acbd29b66aa4122 -size 11019 +oid sha256:cdf7b194a075902ab9434e272865293535ef39370fbb9cb172b3cf8774850c73 +size 19104 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_5_en.png index c74f159222..ceb1513af6 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbab6f0cf6e268e16a631183b05b0c463c22d1ebff2358085f12661f98893c02 -size 14598 +oid sha256:8988c700db517eef71d7f42c8e21ac819f51c92fb88c0c25cb400be7a5326c22 +size 19228 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_6_en.png deleted file mode 100644 index 8338af3af2..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb05d4d4481b1177542a7d5f26a0a9a98e718e20848f08132786073594c19d1a -size 23068 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_7_en.png deleted file mode 100644 index 014429e6b9..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Day_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:804cd2bee1d48ec05a248744de906b659e2a6c62c4d3cf4a90ee6cd2689f2081 -size 25758 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_0_en.png index 953e1db0f9..eed60f472d 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d73cdc2be6545d09165a27d77de3204f1a491c04fc6651913ef3b76b2060339 -size 10548 +oid sha256:da601c01dd487f9c66f78ada91954398e1dcdf699f1ba4f6d8f7661f7b8cc4b7 +size 18715 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_1_en.png index 81fc808eaf..6c424a1ffe 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9b8967a596dcae62399e953af359caa96a0252ba4d4d63b3eaa5c0afb7f61dd -size 27750 +oid sha256:6a62d7b4716f97f73dddd22fc3ecad30ef159da186ff2f2029772f4574a4f474 +size 36084 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_2_en.png index 4c0ec571a5..72196c0b11 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8a950a9808be5828a98a0c84a89a6d5fd08a57e22c50f09de8f48f3cb50309d -size 26337 +oid sha256:10d95b146c51895a0e9e816cf56aa216dfbf77e74ae3da10f9c3fa94468ba9ed +size 34500 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_3_en.png index 953e1db0f9..da90a76ab1 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d73cdc2be6545d09165a27d77de3204f1a491c04fc6651913ef3b76b2060339 -size 10548 +oid sha256:64236eda401891b7a04c9240ed2b9b077b8c08b182b76f454cf0a4376daa740a +size 30345 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_4_en.png index fd49e1b5a8..eed60f472d 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f258316f364bdf365dd71caa913baa22dce9db599233e02ddca73b9ac4bbc6c7 -size 10666 +oid sha256:da601c01dd487f9c66f78ada91954398e1dcdf699f1ba4f6d8f7661f7b8cc4b7 +size 18715 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_5_en.png index 1cb2452f75..d3ee3b9e22 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ac7478f8dbb8195bce194d50008fc9d7dc80d9f40b1d9b2b22e8ddd517c2be5 -size 13941 +oid sha256:ca86fd5eea8c05a52fee801e1ca61c2e4e205ad9874e06d69b1d1f674585f87b +size 18842 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_6_en.png deleted file mode 100644 index 4bd7b317bd..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:29c49cbcaf41b41b7924a57e6d6652e7dd5e5bf90b39815f839c9611cb6237eb -size 22205 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_7_en.png deleted file mode 100644 index 12c581dd09..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.show_ShowLocationView_Night_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb1255327a2ae18b6dc4117e13b2d1e516eec023ef679034c079cddc9c5a4636 -size 24775 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en.png index b92e1ed388..303a32a04d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e0bbf92b3132e3653e909f69b4a4baf06e8889e92aaf904883795ce992cd64f -size 23801 +oid sha256:36926eca7b934f7794ddd73e7929861d8837e9ac51341520c883043dc53d1927 +size 25026 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en.png index a759c0bc53..32c4015a76 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9f6906366e4af0a2171f287dfc6b3e5b46c1a8b41b9a02600ccf6eb5f44a25d -size 23196 +oid sha256:493ed64dc981851887506ce33cdd063a107c8d5e6376027e7949a248b88e2a42 +size 24167 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en.png index 9d11f9e61c..57b0b89912 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0731766e54bdee0fcf7b7ca6c5066fc7a2d17f0c18afad3a5b64d5fea9ac95cc -size 148332 +oid sha256:b2dea1019d3de891dd47d0d5e3b1deefeb0938be82afb72b0dc77c1f14596553 +size 144841 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_2_en.png new file mode 100644 index 0000000000..57b0b89912 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2dea1019d3de891dd47d0d5e3b1deefeb0938be82afb72b0dc77c1f14596553 +size 144841 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en.png index 4d766b1ee2..74add72a23 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2411192232cdd0f359e446768f052cd1675495afdf1d82526343fc8fa42880f9 -size 62469 +oid sha256:9305cafe7cca68c9307577533f3b489566c669cbd4fc08c724c8f492bbd75573 +size 58482 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_2_en.png new file mode 100644 index 0000000000..74add72a23 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9305cafe7cca68c9307577533f3b489566c669cbd4fc08c724c8f492bbd75573 +size 58482 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png index 84cabe4409..bf6cbaadcb 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29e50867fd6e64234317766463d3428187a5171215fb5786f6b16d288cc97692 -size 364448 +oid sha256:6d7b628cc474a421869207c8ffd86e46c193da3e1fe8ea115fb12574528da933 +size 364172 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png index 4195637aa5..38499a5838 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91646548d795c159b94d909276a80ee44ba83b0c95b9d76b2669b6cb4a9f8880 -size 362696 +oid sha256:8b9a9264b6637a35096b2f552a2dbe9f6fa6a078bb631c17bf1d207e10928f07 +size 362463 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png index c8bbd3dcd1..b3255ab5b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffe8ceb923b63331d4b49bcb4d69793f6ce4f82be6e54b7d3470952b35a2da73 -size 332417 +oid sha256:8a87e01d7a14fa40b73c76af0e80c4f2b43ec8cd2f40cb82ef3e321d54f6f341 +size 374820 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png index ce251301d9..b3255ab5b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:877e252ee1e0c35efef1854bf6c94783add9138148a9e910bc7908ee7228209b -size 88375 +oid sha256:8a87e01d7a14fa40b73c76af0e80c4f2b43ec8cd2f40cb82ef3e321d54f6f341 +size 374820 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png index 3907bdf959..ce251301d9 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e157c0f0f115133f36dee9c1f1647fb8f00813a12783b18fa83c6972e92e037 -size 51116 +oid sha256:877e252ee1e0c35efef1854bf6c94783add9138148a9e910bc7908ee7228209b +size 88375 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png index 3ea50dcbe1..3907bdf959 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00be45a05243c429344206d132d0fdbc6322c25c3c71dcab61f939070dd015d3 -size 63156 +oid sha256:6e157c0f0f115133f36dee9c1f1647fb8f00813a12783b18fa83c6972e92e037 +size 51116 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png index b9da99e5c2..3ea50dcbe1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a19d67b394c682e329bc232b0a36c5015dd73d09931b7e401c5d306f922f026 -size 47404 +oid sha256:00be45a05243c429344206d132d0fdbc6322c25c3c71dcab61f939070dd015d3 +size 63156 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png index bd22123444..b9da99e5c2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:205d1785959ccc932b6f307bbe8fc86466eeab2be83ce80b265cb54bf75cdfe3 -size 64392 +oid sha256:8a19d67b394c682e329bc232b0a36c5015dd73d09931b7e401c5d306f922f026 +size 47404 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png index cdd4607e18..bd22123444 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4384708192ccd7ef69601ba4a37b491d1959f8ec84c3e70ceba148d716347952 -size 54368 +oid sha256:205d1785959ccc932b6f307bbe8fc86466eeab2be83ce80b265cb54bf75cdfe3 +size 64392 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png index 32a9dd93d2..cdd4607e18 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c3ebe62e38381e25e85c0be666ab6380811d2fbbea58461b917a0af4c6cb4d8 -size 64322 +oid sha256:4384708192ccd7ef69601ba4a37b491d1959f8ec84c3e70ceba148d716347952 +size 54368 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png new file mode 100644 index 0000000000..32a9dd93d2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c3ebe62e38381e25e85c0be666ab6380811d2fbbea58461b917a0af4c6cb4d8 +size 64322 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png index 99d8ed3cd9..fc5e6d8e98 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a69c582e4e05d2555ffe5e5aaa190eb216a48aa408623a518b0238dcf70a456 -size 148001 +oid sha256:3ac7741cfc4ec1d8fd9c8c5bab7dc3dcc0ba79932b5a1ab325573b7dd3622c4c +size 153022 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png index 80dcc6a601..fc5e6d8e98 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e5dddb25a8a201e5334566c90a252111e0d8a65c9949e4f0b7d3d66b3a4103c -size 83890 +oid sha256:3ac7741cfc4ec1d8fd9c8c5bab7dc3dcc0ba79932b5a1ab325573b7dd3622c4c +size 153022 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png index 7f114a43f2..80dcc6a601 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f225e76a780b6a3eccc66c720f710564b82774250a3f229367b12cdb390928a4 -size 50876 +oid sha256:0e5dddb25a8a201e5334566c90a252111e0d8a65c9949e4f0b7d3d66b3a4103c +size 83890 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png index 161bc26f01..7f114a43f2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed0df44ce25f2a9f7e75d49c48a805f62bbf61f1f63ecee7f29e34f9bcae0e70 -size 61888 +oid sha256:f225e76a780b6a3eccc66c720f710564b82774250a3f229367b12cdb390928a4 +size 50876 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png index d74c89c6aa..161bc26f01 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eeddbe4e53cdf4453db6a7bd0257a52d46cfcac762da73319cf8735aedce481 -size 47422 +oid sha256:ed0df44ce25f2a9f7e75d49c48a805f62bbf61f1f63ecee7f29e34f9bcae0e70 +size 61888 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png index 6ddd6f5648..d74c89c6aa 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:143ae0c737a60e42370c10cdb39c577b91a151fa69079843e740b9edc7c5fc67 -size 63288 +oid sha256:4eeddbe4e53cdf4453db6a7bd0257a52d46cfcac762da73319cf8735aedce481 +size 47422 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png index 1cff467cbe..6ddd6f5648 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4474b2c524768d2493b7ffd6c05b43f486c595c23f1ea641ba7704fad7181d0f -size 53792 +oid sha256:143ae0c737a60e42370c10cdb39c577b91a151fa69079843e740b9edc7c5fc67 +size 63288 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png index ba24c369e1..1cff467cbe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7e7905c6765db72a06c0dba835e34556377fb014476f0ebb2a68a6b93d05314 -size 64889 +oid sha256:4474b2c524768d2493b7ffd6c05b43f486c595c23f1ea641ba7704fad7181d0f +size 53792 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png new file mode 100644 index 0000000000..ba24c369e1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7e7905c6765db72a06c0dba835e34556377fb014476f0ebb2a68a6b93d05314 +size 64889 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png index 70991f651b..ef8699b324 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35e9c8ada35ab52308f16683eec27e973d0c66ee3f8ad5cdfffb6ec4ad20b32e -size 38830 +oid sha256:f21b1799dec6cb466378a748adb5227f76bd6cf611be694922ef63a951fdf692 +size 39910 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png index 35e473c18f..51a300b462 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:761e6215e1554585951626a3ec846526b0dde5ce720e487f379b8c4a074726aa -size 37040 +oid sha256:84a6b1ef879f1a9be16526efdd546aa554e03ea74b0e8ec03178b2a860b752e5 +size 38089 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png new file mode 100644 index 0000000000..1341961018 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ad77b033de161bcd358e7e3afa15a3d5777a6dde319472be9fbcf07d0f5c800 +size 16358 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png new file mode 100644 index 0000000000..dac3588ed9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9767298a096be7fc78210245e6b806a72a6c1ad16d7335e0f89728bbcf08ebd4 +size 15884 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Day_0_en.png deleted file mode 100644 index f758a309b4..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d3ca357675ca4328041237cb4b9d8a5725c2a37007e242395742fc8f65b4bec9 -size 4732 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Night_0_en.png deleted file mode 100644 index b174bdbfdd..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_PinIcon_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:25bb33b880f2ce4eafcb2a34ac1a6cf806da8820caa95c46883a525b50c784fe -size 4731 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en.png index 28bf34a5a4..54ad34decf 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c5a90fc9dc608cc080c473c127289aba3a75c1b04b7353cdf053a625ab45aaf -size 4957 +oid sha256:9a0f68b963d169fead1b012792aeaa890cfa1631370b6f276e39e5c23febebda +size 4749 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en.png index 9316c24d4c..1a2ae3b794 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a56fa04f2d2e98a0a9147fae158e7921ee533290feb6e08b3111fdb4c6d21c43 -size 4939 +oid sha256:6e787d1d35de4d2473ae5b59a8c77c129bb6d8baed05e8dd243edaafb7038639 +size 4795 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png index c0a170e9de..789e6ad754 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e34ddf667db8e18e9554f476cf120766c3882ea8155818ffae3a313c4b88d433 -size 9048 +oid sha256:936f352e9c70919e2f5d325dee2eb3048b625e77bbdc0ac1685d023c131a7cb2 +size 8977 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png index 2840f32904..8220e6b24a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:afcaa0043c17025cbacaf6964ba681a11949ae1241da30aa6a6ab8ebcf3cd19e -size 8839 +oid sha256:8799ed0f6c481130b4f1e3b5ff2c47148e84d5d26aa94559643b82f6db5a3521 +size 8756 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png index 5ef915812c..222210f39f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d23fdafbd834da43a6fe57d5666fc6a3108359838053961a419a9b90a1f7aa53 -size 67001 +oid sha256:de9d73aa7c19275f9a97d81a99d85f9e03fb38b19a0313e0920034d49f88c0aa +size 66768 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png index 86e8f3d34c..4f13f41ce4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df811a1843d3d88ac021d8df892c2b74f61a679317ed40234438459833b90fa9 -size 64134 +oid sha256:5da7140b7701c19dcf429afc0b379c02b4572806fc97a11609b112253270f8ef +size 64018 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png index fc69d0c81c..ae05740f43 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f924131a517897decc596cf360b7aed621a358a1a58ad7e5e512e5caab6203c -size 67493 +oid sha256:1351eeea2c6bf92f358ceb8ce7021e7f7dc0cfb34525ed3757987b85d2ca10f4 +size 67235 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png index b1ac77f79d..628ab387ab 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f42650a174ccfee6dbf722045a0147d0ff5e5f3a0d7fcdd14a46a32bbf9ddb6 -size 64628 +oid sha256:c64d685b7710e864b6e0beaa8f77061e07874b8ec15f1f2bb04c484a08d570c1 +size 64416 From 7c6a5638ad104e1dcf61c85b0fa5defdeba308c1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 10:18:28 +0100 Subject: [PATCH 040/103] Fix some existing tests after changes --- .../MapTilerStaticMapUrlBuilderTest.kt | 24 +++++++++---------- .../location/impl/share/ShareLocationView.kt | 2 ++ ...efaultPinnedMessagesBannerFormatterTest.kt | 2 +- .../DefaultRoomLatestEventFormatterTest.kt | 2 +- .../messages/reply/InReplyToMetadataKtTest.kt | 1 + .../datasource/DefaultEventItemFactoryTest.kt | 2 +- .../DefaultNotifiableEventResolverTest.kt | 2 +- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/features/location/api/src/test/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilderTest.kt b/features/location/api/src/test/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilderTest.kt index 65c0acd88d..3d17107104 100644 --- a/features/location/api/src/test/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilderTest.kt +++ b/features/location/api/src/test/kotlin/io/element/android/features/location/api/internal/MapTilerStaticMapUrlBuilderTest.kt @@ -47,7 +47,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 600, density = 1f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600.webp?key=anApiKey&attribution=topright") } @Test @@ -62,7 +62,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 900, density = 1.5f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600.webp?key=anApiKey&attribution=topright") } @Test @@ -77,7 +77,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 1200, density = 2f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600@2x.webp?key=anApiKey&attribution=topright") } @Test @@ -92,7 +92,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 1800, density = 3f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/800x600@2x.webp?key=anApiKey&attribution=topright") } @Test @@ -107,7 +107,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 2048, density = 1f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/2048x1024.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/2048x1024.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -119,7 +119,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 4096, density = 1f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x2048.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x2048.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -131,7 +131,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 2048, density = 2f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x512@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x512@2x.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -143,7 +143,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 4096, density = 2f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/512x1024@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/512x1024@2x.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -155,7 +155,7 @@ class MapTilerStaticMapUrlBuilderTest { height = Int.MAX_VALUE, density = 2f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x1024@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/1024x1024@2x.webp?key=anApiKey&attribution=topright") } @Test @@ -170,7 +170,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 0, density = 1f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -182,7 +182,7 @@ class MapTilerStaticMapUrlBuilderTest { height = 0, density = 2f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0@2x.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0@2x.webp?key=anApiKey&attribution=topright") assertThat( builder.build( @@ -194,6 +194,6 @@ class MapTilerStaticMapUrlBuilderTest { height = Int.MIN_VALUE, density = 1f, ) - ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0.webp?key=anApiKey&attribution=bottomleft") + ).isEqualTo("https://base.url/aLightMapId/static/-4.56,1.23,7.8/0x0.webp?key=anApiKey&attribution=topright") } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index ecb4cf9dd4..b463d494dc 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -6,6 +6,8 @@ * Please see LICENSE files in the repository root for full details. */ +@file:Suppress("COMPOSE_APPLIER_CALL_MISMATCH") + package io.element.android.features.location.impl.share import androidx.compose.foundation.layout.Arrangement diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt index b58bbb4b25..e91bed409e 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt @@ -145,7 +145,7 @@ class DefaultPinnedMessagesBannerFormatterTest { ImageMessageType(body, null, null, MediaSource("url"), null), StickerMessageType(body, null, null, MediaSource("url"), null), FileMessageType(body, null, null, MediaSource("url"), null), - LocationMessageType(body, "geo:1,2", null), + LocationMessageType(body, "geo:1,2", null, null), NoticeMessageType(body, null), EmoteMessageType(body, null), OtherMessageType(msgType = "a_type", body = body), diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt index 0da3134098..2345af8a33 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt @@ -190,7 +190,7 @@ class DefaultRoomLatestEventFormatterTest { ImageMessageType(body, null, null, MediaSource("url"), null), StickerMessageType(body, null, null, MediaSource("url"), null), FileMessageType(body, null, null, MediaSource("url"), null), - LocationMessageType(body, "geo:1,2", null), + LocationMessageType(body, "geo:1,2", null, null), NoticeMessageType(body, null), EmoteMessageType(body, null), OtherMessageType(msgType = "a_type", body = body), diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt index 004e622211..5c7fdfaac8 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt @@ -355,6 +355,7 @@ class InReplyToMetadataKtTest { body = "body", geoUri = "geo:3.0,4.0;u=5.0", description = null, + assetType = null ) ) ).metadata(hideImage = false) diff --git a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt index c70d658418..6c88f1c33f 100644 --- a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt +++ b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt @@ -107,7 +107,7 @@ class DefaultEventItemFactoryTest { EmoteMessageType("", null), NoticeMessageType("", null), OtherMessageType("", ""), - LocationMessageType("", "", null), + LocationMessageType("", "", null, null), TextMessageType("", null) ) messageTypes.forEach { diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index a25e5782ba..63b903a3f7 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -339,7 +339,7 @@ class DefaultNotifiableEventResolverTest { AN_EVENT_ID to Result.success(aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, - messageType = LocationMessageType("Location", "geo:1,2", null), + messageType = LocationMessageType("Location", "geo:1,2", null, null), ), )) ) From 249d45ce04a95a8cb44fd1f32e43038fb2e3a273 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 15:08:17 +0100 Subject: [PATCH 041/103] Fix wrong dependency --- features/location/impl/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index c7b19fbf59..14dd7a7836 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -45,7 +45,7 @@ dependencies { testCommonDependencies(libs, true) testImplementation(projects.libraries.matrix.test) - implementation(projects.libraries.dateformatter.test) + testImplementation(projects.libraries.dateformatter.test) testImplementation(projects.libraries.testtags) testImplementation(projects.services.analytics.test) testImplementation(projects.features.messages.test) From 83832a38f9adeac2726e88f3fba3ca7c5ed1f02a Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 15:48:56 +0100 Subject: [PATCH 042/103] Fix stability --- .../impl/show/ShowLocationPresenter.kt | 14 +-- .../location/impl/show/ShowLocationState.kt | 7 +- .../impl/show/ShowLocationStateProvider.kt | 106 ++++++++---------- .../location/impl/show/ShowLocationView.kt | 20 ++-- 4 files changed, 69 insertions(+), 78 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index d74d2f36e1..9978c6e1f5 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -37,6 +37,7 @@ import io.element.android.libraries.designsystem.components.PinVariant 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.room.location.AssetType +import kotlinx.collections.immutable.persistentListOf @AssistedInject class ShowLocationPresenter( @@ -95,7 +96,7 @@ class ShowLocationPresenter( } } - val markers = remember(mode) { + val markers = remember { when (mode) { is ShowLocationMode.Static -> { val pinVariant = if (mode.assetType == AssetType.PIN) { @@ -111,7 +112,7 @@ class ShowLocationPresenter( isLive = false, ) } - listOf( + persistentListOf( LocationMarkerData( id = mode.senderId.value, location = mode.location, @@ -119,16 +120,16 @@ class ShowLocationPresenter( ) ) } - ShowLocationMode.Live -> emptyList() + ShowLocationMode.Live -> persistentListOf() } } - val locationShares = remember(mode) { + val locationShares = remember { when (mode) { is ShowLocationMode.Static -> { val relativeTime = dateFormatter.format(timestamp = mode.timestamp, mode = DateFormatterMode.Full, useRelative = true) val formattedTimestamp = "Shared $relativeTime" - listOf( + persistentListOf( LocationShareItem( userId = mode.senderId, displayName = mode.senderName, @@ -145,13 +146,12 @@ class ShowLocationPresenter( ) ) } - ShowLocationMode.Live -> emptyList() + ShowLocationMode.Live -> persistentListOf() } } return ShowLocationState( dialogState = dialogState, - mode = mode, markers = markers, locationShares = locationShares, hasLocationPermission = permissionsState.isAnyGranted, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index 85d79f1192..f6c2e6e18f 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -9,18 +9,17 @@ package io.element.android.features.location.impl.show import io.element.android.features.location.api.Location -import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType +import kotlinx.collections.immutable.ImmutableList data class ShowLocationState( val dialogState: LocationConstraintsDialogState, - val mode: ShowLocationMode, - val markers: List, - val locationShares: List, + val markers: ImmutableList, + val locationShares: ImmutableList, val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, val appName: String, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 9bbd818f1a..274ccfc8f2 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -10,7 +10,6 @@ package io.element.android.features.location.impl.show import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location -import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.designsystem.components.PinVariant @@ -18,6 +17,7 @@ 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.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType +import kotlinx.collections.immutable.toImmutableList private const val APP_NAME = "ApplicationName" @@ -45,62 +45,23 @@ class ShowLocationStateProvider : PreviewParameterProvider { ) } +private val defaultLocation = Location(1.23, 2.34, 4f) +private val defaultSenderId = UserId("@alice:matrix.org") +private const val defaultSenderName = "Alice" + fun aShowLocationState( constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None, - mode: ShowLocationMode = aStaticLocationMode(), - markers: List? = null, - locationSharers: List? = null, + markers: List = listOf(aLocationMarkerData()), + locationShares: List = listOf(aLocationShareItem()), hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, appName: String = APP_NAME, eventSink: (ShowLocationEvent) -> Unit = {}, ): ShowLocationState { - val effectiveMarkers = markers ?: when (mode) { - is ShowLocationMode.Static -> listOf( - LocationMarkerData( - id = mode.senderId.value, - location = mode.location, - variant = if (mode.assetType == AssetType.PIN) { - PinVariant.PinnedLocation - } else { - PinVariant.UserLocation( - avatarData = AvatarData( - id = mode.senderId.value, - name = mode.senderName, - url = mode.senderAvatarUrl, - size = AvatarSize.LocationPin, - ), - isLive = true, - ) - } - ) - ) - ShowLocationMode.Live -> emptyList() - } - val effectiveLocationSharers = locationSharers ?: when (mode) { - is ShowLocationMode.Static -> listOf( - LocationShareItem( - userId = mode.senderId, - displayName = mode.senderName, - avatarData = AvatarData( - id = mode.senderId.value, - name = mode.senderName, - url = mode.senderAvatarUrl, - size = AvatarSize.UserListItem, - ), - formattedTimestamp = "Shared 1 min ago", - isLive = false, - assetType = mode.assetType, - location = mode.location, - ) - ) - ShowLocationMode.Live -> emptyList() - } return ShowLocationState( dialogState = constraintsDialogState, - mode = mode, - markers = effectiveMarkers, - locationShares = effectiveLocationSharers, + markers = markers.toImmutableList(), + locationShares = locationShares.toImmutableList(), hasLocationPermission = hasLocationPermission, isTrackMyLocation = isTrackMyLocation, appName = appName, @@ -108,18 +69,43 @@ fun aShowLocationState( ) } -fun aStaticLocationMode( - location: Location = Location(1.23, 2.34, 4f), - senderName: String = "Alice", - senderId: UserId = UserId("@alice:matrix.org"), - senderAvatarUrl: String? = null, - timestamp: Long = System.currentTimeMillis(), - assetType: AssetType? = null, -) = ShowLocationMode.Static( +fun aLocationMarkerData( + id: String = defaultSenderId.value, + location: Location = defaultLocation, + variant: PinVariant = PinVariant.UserLocation( + avatarData = AvatarData( + id = defaultSenderId.value, + name = defaultSenderName, + url = null, + size = AvatarSize.LocationPin, + ), + isLive = false, + ), +) = LocationMarkerData( + id = id, location = location, - senderName = senderName, - senderId = senderId, - senderAvatarUrl = senderAvatarUrl, - timestamp = timestamp, + variant = variant, +) + +fun aLocationShareItem( + userId: UserId = defaultSenderId, + displayName: String = defaultSenderName, + avatarData: AvatarData = AvatarData( + id = defaultSenderId.value, + name = defaultSenderName, + url = null, + size = AvatarSize.UserListItem, + ), + formattedTimestamp: String = "Shared 1 min ago", + location: Location = defaultLocation, + isLive: Boolean = false, + assetType: AssetType? = null, +) = LocationShareItem( + userId = userId, + displayName = displayName, + avatarData = avatarData, + formattedTimestamp = formattedTimestamp, + location = location, + isLive = isLive, assetType = assetType, ) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index fdeb027b1e..d97cef81d0 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -6,6 +6,8 @@ * Please see LICENSE files in the repository root for full details. */ +@file:Suppress("COMPOSE_APPLIER_CALL_MISMATCH") + package io.element.android.features.location.impl.show import androidx.compose.foundation.clickable @@ -19,6 +21,7 @@ import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -26,7 +29,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.features.location.api.ShowLocationMode import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton @@ -63,12 +65,16 @@ fun ShowLocationView( onDismiss = { state.eventSink(ShowLocationEvent.DismissDialog) }, ) - val initialPosition = when (val mode = state.mode) { - is ShowLocationMode.Static -> CameraPosition( - target = Position(latitude = mode.location.lat, longitude = mode.location.lon), - zoom = MapDefaults.DEFAULT_ZOOM - ) - ShowLocationMode.Live -> MapDefaults.defaultCameraPosition + val initialPosition = remember { + if (state.markers.isEmpty()) { + MapDefaults.defaultCameraPosition + } else { + val firstLocation = state.markers.first().location + CameraPosition( + target = Position(latitude = firstLocation.lat, longitude = firstLocation.lon), + zoom = MapDefaults.DEFAULT_ZOOM + ) + } } val cameraState = rememberCameraState(firstPosition = initialPosition) val userLocationState = rememberUserLocationState(state.hasLocationPermission) From 91c46ec971cd88a9a35d3466eaaf52f996c2fdc7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 15:50:33 +0100 Subject: [PATCH 043/103] Remove duplicate location content and reorder Live mode --- .../timeline/model/event/TimelineItemEventContentProvider.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt index 017fba1902..f3d70f44e7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContentProvider.kt @@ -28,15 +28,14 @@ class TimelineItemEventContentProvider : PreviewParameterProvider Date: Fri, 13 Mar 2026 15:10:17 +0000 Subject: [PATCH 044/103] Update screenshots --- ...features.messages.impl.timeline_TimelineView_Day_10_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_11_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_12_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_13_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_14_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_15_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_16_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_17_en.png | 4 ++-- ...features.messages.impl.timeline_TimelineView_Day_18_en.png | 3 --- ...atures.messages.impl.timeline_TimelineView_Night_10_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_11_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_12_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_13_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_14_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_15_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_16_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_17_en.png | 4 ++-- ...atures.messages.impl.timeline_TimelineView_Night_18_en.png | 3 --- ...libraries.designsystem.components_LocationPin_Day_0_en.png | 4 ++-- 19 files changed, 34 insertions(+), 40 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png index b3255ab5b5..ce251301d9 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a87e01d7a14fa40b73c76af0e80c4f2b43ec8cd2f40cb82ef3e321d54f6f341 -size 374820 +oid sha256:877e252ee1e0c35efef1854bf6c94783add9138148a9e910bc7908ee7228209b +size 88375 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png index b3255ab5b5..3907bdf959 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a87e01d7a14fa40b73c76af0e80c4f2b43ec8cd2f40cb82ef3e321d54f6f341 -size 374820 +oid sha256:6e157c0f0f115133f36dee9c1f1647fb8f00813a12783b18fa83c6972e92e037 +size 51116 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png index ce251301d9..3ea50dcbe1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:877e252ee1e0c35efef1854bf6c94783add9138148a9e910bc7908ee7228209b -size 88375 +oid sha256:00be45a05243c429344206d132d0fdbc6322c25c3c71dcab61f939070dd015d3 +size 63156 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png index 3907bdf959..b9da99e5c2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e157c0f0f115133f36dee9c1f1647fb8f00813a12783b18fa83c6972e92e037 -size 51116 +oid sha256:8a19d67b394c682e329bc232b0a36c5015dd73d09931b7e401c5d306f922f026 +size 47404 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png index 3ea50dcbe1..bd22123444 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00be45a05243c429344206d132d0fdbc6322c25c3c71dcab61f939070dd015d3 -size 63156 +oid sha256:205d1785959ccc932b6f307bbe8fc86466eeab2be83ce80b265cb54bf75cdfe3 +size 64392 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png index b9da99e5c2..cdd4607e18 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a19d67b394c682e329bc232b0a36c5015dd73d09931b7e401c5d306f922f026 -size 47404 +oid sha256:4384708192ccd7ef69601ba4a37b491d1959f8ec84c3e70ceba148d716347952 +size 54368 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png index bd22123444..32a9dd93d2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:205d1785959ccc932b6f307bbe8fc86466eeab2be83ce80b265cb54bf75cdfe3 -size 64392 +oid sha256:8c3ebe62e38381e25e85c0be666ab6380811d2fbbea58461b917a0af4c6cb4d8 +size 64322 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png index cdd4607e18..b3255ab5b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4384708192ccd7ef69601ba4a37b491d1959f8ec84c3e70ceba148d716347952 -size 54368 +oid sha256:8a87e01d7a14fa40b73c76af0e80c4f2b43ec8cd2f40cb82ef3e321d54f6f341 +size 374820 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png deleted file mode 100644 index 32a9dd93d2..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_18_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c3ebe62e38381e25e85c0be666ab6380811d2fbbea58461b917a0af4c6cb4d8 -size 64322 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png index fc5e6d8e98..80dcc6a601 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac7741cfc4ec1d8fd9c8c5bab7dc3dcc0ba79932b5a1ab325573b7dd3622c4c -size 153022 +oid sha256:0e5dddb25a8a201e5334566c90a252111e0d8a65c9949e4f0b7d3d66b3a4103c +size 83890 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png index fc5e6d8e98..7f114a43f2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac7741cfc4ec1d8fd9c8c5bab7dc3dcc0ba79932b5a1ab325573b7dd3622c4c -size 153022 +oid sha256:f225e76a780b6a3eccc66c720f710564b82774250a3f229367b12cdb390928a4 +size 50876 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png index 80dcc6a601..161bc26f01 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e5dddb25a8a201e5334566c90a252111e0d8a65c9949e4f0b7d3d66b3a4103c -size 83890 +oid sha256:ed0df44ce25f2a9f7e75d49c48a805f62bbf61f1f63ecee7f29e34f9bcae0e70 +size 61888 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png index 7f114a43f2..d74c89c6aa 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f225e76a780b6a3eccc66c720f710564b82774250a3f229367b12cdb390928a4 -size 50876 +oid sha256:4eeddbe4e53cdf4453db6a7bd0257a52d46cfcac762da73319cf8735aedce481 +size 47422 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png index 161bc26f01..6ddd6f5648 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed0df44ce25f2a9f7e75d49c48a805f62bbf61f1f63ecee7f29e34f9bcae0e70 -size 61888 +oid sha256:143ae0c737a60e42370c10cdb39c577b91a151fa69079843e740b9edc7c5fc67 +size 63288 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png index d74c89c6aa..1cff467cbe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eeddbe4e53cdf4453db6a7bd0257a52d46cfcac762da73319cf8735aedce481 -size 47422 +oid sha256:4474b2c524768d2493b7ffd6c05b43f486c595c23f1ea641ba7704fad7181d0f +size 53792 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png index 6ddd6f5648..ba24c369e1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:143ae0c737a60e42370c10cdb39c577b91a151fa69079843e740b9edc7c5fc67 -size 63288 +oid sha256:f7e7905c6765db72a06c0dba835e34556377fb014476f0ebb2a68a6b93d05314 +size 64889 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png index 1cff467cbe..fc5e6d8e98 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4474b2c524768d2493b7ffd6c05b43f486c595c23f1ea641ba7704fad7181d0f -size 53792 +oid sha256:3ac7741cfc4ec1d8fd9c8c5bab7dc3dcc0ba79932b5a1ab325573b7dd3622c4c +size 153022 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png deleted file mode 100644 index ba24c369e1..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_18_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f7e7905c6765db72a06c0dba835e34556377fb014476f0ebb2a68a6b93d05314 -size 64889 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png index 1341961018..8dda833412 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ad77b033de161bcd358e7e3afa15a3d5777a6dde319472be9fbcf07d0f5c800 -size 16358 +oid sha256:4f3df9c9de000b15692b982c7d69f85ce3d03cab468c342773c88eff3b4fca65 +size 9082 From 9b98a4794143323b0cc784ee1cdc8fe50523ebb4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 18:41:13 +0100 Subject: [PATCH 045/103] Use localized string instead of hardcoded --- features/location/impl/build.gradle.kts | 2 +- .../features/location/impl/show/ShowLocationPresenter.kt | 8 +++++++- .../impl/show/DefaultShowLocationEntryPointTest.kt | 2 ++ .../location/impl/show/ShowLocationPresenterTest.kt | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/features/location/impl/build.gradle.kts b/features/location/impl/build.gradle.kts index 14dd7a7836..0da54a1394 100644 --- a/features/location/impl/build.gradle.kts +++ b/features/location/impl/build.gradle.kts @@ -36,7 +36,6 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.core) implementation(projects.libraries.matrixui) - implementation(projects.libraries.androidutils) implementation(projects.services.analytics.api) implementation(libs.accompanist.permission) implementation(projects.libraries.uiStrings) @@ -46,6 +45,7 @@ dependencies { testCommonDependencies(libs, true) testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.dateformatter.test) + testImplementation(projects.services.toolbox.test) testImplementation(projects.libraries.testtags) testImplementation(projects.services.analytics.test) testImplementation(projects.features.messages.test) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 9978c6e1f5..7ecab4924e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -37,6 +37,8 @@ import io.element.android.libraries.designsystem.components.PinVariant 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.room.location.AssetType +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.services.toolbox.api.strings.StringProvider import kotlinx.collections.immutable.persistentListOf @AssistedInject @@ -46,6 +48,7 @@ class ShowLocationPresenter( private val locationActions: LocationActions, private val buildMeta: BuildMeta, private val dateFormatter: DateFormatter, + private val stringProvider: StringProvider, ) : Presenter { @AssistedFactory fun interface Factory { @@ -128,7 +131,10 @@ class ShowLocationPresenter( when (mode) { is ShowLocationMode.Static -> { val relativeTime = dateFormatter.format(timestamp = mode.timestamp, mode = DateFormatterMode.Full, useRelative = true) - val formattedTimestamp = "Shared $relativeTime" + val formattedTimestamp = stringProvider.getString( + CommonStrings.screen_static_location_sheet_timestamp_description, + relativeTime + ) persistentListOf( LocationShareItem( userId = mode.senderId, diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt index b8a32e5912..451531fc7e 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/DefaultShowLocationEntryPointTest.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.toolbox.test.strings.FakeStringProvider import io.element.android.tests.testutils.node.TestParentNode import org.junit.Rule import org.junit.Test @@ -42,6 +43,7 @@ class DefaultShowLocationEntryPointTest { locationActions = FakeLocationActions(), buildMeta = aBuildMeta(), dateFormatter = FakeDateFormatter(), + stringProvider = FakeStringProvider() ) }, analyticsService = FakeAnalyticsService(), diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt index 8a29f0463d..931dd55cea 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt @@ -23,6 +23,7 @@ import io.element.android.features.location.impl.common.ui.LocationConstraintsDi import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.services.toolbox.test.strings.FakeStringProvider import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import kotlinx.coroutines.delay @@ -56,6 +57,7 @@ class ShowLocationPresenterTest { locationActions = locationActions, buildMeta = fakeBuildMeta, dateFormatter = fakeDateFormatter, + stringProvider = FakeStringProvider() ) @Test From 6414d74c40141140c1d18d12fb8993263165be6c Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 13 Mar 2026 18:41:32 +0100 Subject: [PATCH 046/103] Simplify ShowLocationState --- .../impl/common/ui/LocationShareRow.kt | 10 +++-- .../impl/show/ShowLocationPresenter.kt | 34 +---------------- .../location/impl/show/ShowLocationState.kt | 18 ++++++++- .../impl/show/ShowLocationStateProvider.kt | 38 +++---------------- .../location/impl/show/ShowLocationView.kt | 9 +++-- 5 files changed, 37 insertions(+), 72 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt index 9e5e35b2ba..b949f55c76 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationShareRow.kt @@ -78,7 +78,11 @@ fun LocationShareRow( modifier = Modifier.size(16.dp), ) } else { - val icon = if (item.assetType == AssetType.PIN) CompoundIcons.LocationNavigator() else CompoundIcons.LocationNavigatorCentred() + val icon = if (item.assetType == AssetType.PIN) { + CompoundIcons.LocationNavigator() + } else { + CompoundIcons.LocationNavigatorCentred() + } Icon( imageVector = icon, contentDescription = null, @@ -120,8 +124,8 @@ internal fun LocationShareRowPreview() = ElementPreview { size = AvatarSize.UserListItem, ), formattedTimestamp = "Shared 1 min ago", - assetType = AssetType.SENDER, isLive = true, + assetType = AssetType.SENDER, location = Location(0.0, 0.0) ), onShareClick = {}, @@ -136,9 +140,9 @@ internal fun LocationShareRowPreview() = ElementPreview { url = null, size = AvatarSize.UserListItem, ), + isLive = false, assetType = AssetType.PIN, formattedTimestamp = "Shared 5 hours ago", - isLive = false, location = Location(0.0, 0.0) ), onShareClick = {}, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt index 7ecab4924e..a2c9a3702d 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt @@ -28,15 +28,12 @@ import io.element.android.features.location.impl.common.permissions.PermissionsP import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.features.location.impl.common.toDialogState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState -import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatterMode -import io.element.android.libraries.designsystem.components.PinVariant 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.room.location.AssetType import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.toolbox.api.strings.StringProvider import kotlinx.collections.immutable.persistentListOf @@ -99,34 +96,6 @@ class ShowLocationPresenter( } } - val markers = remember { - when (mode) { - is ShowLocationMode.Static -> { - val pinVariant = if (mode.assetType == AssetType.PIN) { - PinVariant.PinnedLocation - } else { - PinVariant.UserLocation( - avatarData = AvatarData( - id = mode.senderId.value, - name = mode.senderName, - url = mode.senderAvatarUrl, - size = AvatarSize.UserListItem, - ), - isLive = false, - ) - } - persistentListOf( - LocationMarkerData( - id = mode.senderId.value, - location = mode.location, - variant = pinVariant, - ) - ) - } - ShowLocationMode.Live -> persistentListOf() - } - } - val locationShares = remember { when (mode) { is ShowLocationMode.Static -> { @@ -146,9 +115,9 @@ class ShowLocationPresenter( size = AvatarSize.UserListItem, ), formattedTimestamp = formattedTimestamp, + location = mode.location, isLive = false, assetType = mode.assetType, - location = mode.location, ) ) } @@ -158,7 +127,6 @@ class ShowLocationPresenter( return ShowLocationState( dialogState = dialogState, - markers = markers, locationShares = locationShares, hasLocationPermission = permissionsState.isAnyGranted, isTrackMyLocation = isTrackMyLocation, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt index f6c2e6e18f..9494db12ec 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationState.kt @@ -11,6 +11,7 @@ package io.element.android.features.location.impl.show import io.element.android.features.location.api.Location import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationMarkerData +import io.element.android.libraries.designsystem.components.PinVariant import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType @@ -18,7 +19,6 @@ import kotlinx.collections.immutable.ImmutableList data class ShowLocationState( val dialogState: LocationConstraintsDialogState, - val markers: ImmutableList, val locationShares: ImmutableList, val hasLocationPermission: Boolean, val isTrackMyLocation: Boolean, @@ -37,3 +37,19 @@ data class LocationShareItem( val isLive: Boolean, val assetType: AssetType?, ) + +fun LocationShareItem.toMarkerData(): LocationMarkerData { + val pinVariant = if (assetType == AssetType.PIN) { + PinVariant.PinnedLocation + } else { + PinVariant.UserLocation( + avatarData = avatarData, + isLive = isLive, + ) + } + return LocationMarkerData( + id = userId.value, + location = location, + variant = pinVariant, + ) +} diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt index 274ccfc8f2..8bee410715 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt @@ -11,16 +11,12 @@ package io.element.android.features.location.impl.show import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.api.Location import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState -import io.element.android.features.location.impl.common.ui.LocationMarkerData -import io.element.android.libraries.designsystem.components.PinVariant 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.core.UserId import io.element.android.libraries.matrix.api.room.location.AssetType import kotlinx.collections.immutable.toImmutableList -private const val APP_NAME = "ApplicationName" - class ShowLocationStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( @@ -45,13 +41,10 @@ class ShowLocationStateProvider : PreviewParameterProvider { ) } -private val defaultLocation = Location(1.23, 2.34, 4f) -private val defaultSenderId = UserId("@alice:matrix.org") -private const val defaultSenderName = "Alice" +private const val APP_NAME = "ApplicationName" fun aShowLocationState( constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None, - markers: List = listOf(aLocationMarkerData()), locationShares: List = listOf(aLocationShareItem()), hasLocationPermission: Boolean = false, isTrackMyLocation: Boolean = false, @@ -60,7 +53,6 @@ fun aShowLocationState( ): ShowLocationState { return ShowLocationState( dialogState = constraintsDialogState, - markers = markers.toImmutableList(), locationShares = locationShares.toImmutableList(), hasLocationPermission = hasLocationPermission, isTrackMyLocation = isTrackMyLocation, @@ -69,35 +61,17 @@ fun aShowLocationState( ) } -fun aLocationMarkerData( - id: String = defaultSenderId.value, - location: Location = defaultLocation, - variant: PinVariant = PinVariant.UserLocation( - avatarData = AvatarData( - id = defaultSenderId.value, - name = defaultSenderName, - url = null, - size = AvatarSize.LocationPin, - ), - isLive = false, - ), -) = LocationMarkerData( - id = id, - location = location, - variant = variant, -) - fun aLocationShareItem( - userId: UserId = defaultSenderId, - displayName: String = defaultSenderName, + userId: UserId = UserId("@alice:matrix.org"), + displayName: String = "Alice", avatarData: AvatarData = AvatarData( - id = defaultSenderId.value, - name = defaultSenderName, + id = userId.value, + name = displayName, url = null, size = AvatarSize.UserListItem, ), formattedTimestamp: String = "Shared 1 min ago", - location: Location = defaultLocation, + location: Location = Location(1.23, 2.34, 4f), isLive: Boolean = false, assetType: AssetType? = null, ) = LocationShareItem( diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt index d97cef81d0..ad2d4cb8ca 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt @@ -66,10 +66,10 @@ fun ShowLocationView( ) val initialPosition = remember { - if (state.markers.isEmpty()) { + if (state.locationShares.isEmpty()) { MapDefaults.defaultCameraPosition } else { - val firstLocation = state.markers.first().location + val firstLocation = state.locationShares.first().location CameraPosition( target = Position(latitude = firstLocation.lat, longitude = firstLocation.lon), zoom = MapDefaults.DEFAULT_ZOOM @@ -147,7 +147,10 @@ fun ShowLocationView( locationState = userLocationState, trackUserLocation = state.isTrackMyLocation ) - LocationPinMarkers(state.markers) + val markers = remember(state.locationShares) { + state.locationShares.map { it.toMarkerData() } + } + LocationPinMarkers(markers) }, overlayContent = { LocationFloatingActionButton( From 3bcfd9ce2df7e56c09ae02ae6ca085797650cea3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:22:37 +0000 Subject: [PATCH 047/103] fix(deps): update dependency io.element.android:element-call-embedded 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 fc6c552db0..e8038373fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -232,7 +232,7 @@ sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0" metro_runtime = { module = "dev.zacsweers.metro:runtime", version.ref = "metro" } # Element Call -element_call_embedded = "io.element.android:element-call-embedded:0.17.0" +element_call_embedded = "io.element.android:element-call-embedded:0.18.0" # Auto services google_autoservice = { module = "com.google.auto.service:auto-service", version.ref = "autoservice" } From abdbc24b474edebc00096007827a63884786788e Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 20 Mar 2026 18:15:44 +0100 Subject: [PATCH 048/103] fix padding on map when gesture navigation is on --- .../location/impl/common/ui/MapBottomSheetScaffold.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt index 09c5067e1a..fbaed9c854 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt @@ -18,7 +18,7 @@ import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.only -import androidx.compose.foundation.layout.safeContent +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.material3.BottomSheetDefaults @@ -93,7 +93,7 @@ fun MapBottomSheetScaffold( ) { val density = LocalDensity.current - val windowInsets = WindowInsets.safeContent.only(WindowInsetsSides.Horizontal) + val windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) BoxWithConstraints(modifier = modifier.windowInsetsPadding(windowInsets)) { val layoutHeightPx by rememberUpdatedState(constraints.maxHeight) val sheetPadding by remember { From 987fa21bdf8da5e46b75ba9f8df6c4cd7e04d688 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:56:29 +0000 Subject: [PATCH 049/103] fix(deps): update kotlin to v2.3.20 --- 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 343e0c43f1..cfaf829d74 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ # Project android_gradle_plugin = "8.13.2" # When updateing this, please also update the version in the file ./idea/kotlinc.xml -kotlin = "2.3.10" +kotlin = "2.3.20" kotlinpoet = "2.2.0" ksp = "2.3.6" firebaseAppDistribution = "5.2.1" From 01d6417971c269380487eddd33de45638dffa197 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:40:04 +0000 Subject: [PATCH 050/103] chore(deps): update nschloe/action-cached-lfs-checkout action to v1.2.4 --- .github/workflows/generate_github_pages.yml | 2 +- .github/workflows/nightlyReports.yml | 2 +- .github/workflows/recordScreenshots.yml | 4 ++-- .github/workflows/tests.yml | 2 +- .github/workflows/validate-lfs.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/generate_github_pages.yml b/.github/workflows/generate_github_pages.yml index f7a9953b0d..e4fedf76ac 100644 --- a/.github/workflows/generate_github_pages.yml +++ b/.github/workflows/generate_github_pages.yml @@ -14,7 +14,7 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} steps: - name: ā¬ Checkout with LFS - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 - name: Use JDK 21 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index 2fbac726fe..ae5c72a3d9 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -34,7 +34,7 @@ jobs: swap-storage: false - name: ā¬ Checkout with LFS - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 - name: Use JDK 21 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 diff --git a/.github/workflows/recordScreenshots.yml b/.github/workflows/recordScreenshots.yml index 294ac0ce1a..189ae26cf3 100644 --- a/.github/workflows/recordScreenshots.yml +++ b/.github/workflows/recordScreenshots.yml @@ -43,13 +43,13 @@ jobs: labels: Record-Screenshots - name: ā¬ Checkout with LFS (PR) if: github.event.label.name == 'Record-Screenshots' - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 with: persist-credentials: false ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }} - name: ā¬ Checkout with LFS (Branch) if: github.event_name == 'workflow_dispatch' - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 with: persist-credentials: false - name: ā˜•ļø Use JDK 21 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 42c8280bc2..602ad1e18e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -49,7 +49,7 @@ jobs: sudo swapon /mnt/swapfile sudo swapon --show - name: ā¬ Checkout with LFS - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/validate-lfs.yml b/.github/workflows/validate-lfs.yml index 3d35a5cba2..c3158291c3 100644 --- a/.github/workflows/validate-lfs.yml +++ b/.github/workflows/validate-lfs.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest name: Validate steps: - - uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 # v1.2.3 + - uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 - run: | ./tools/git/validate_lfs.sh From 54bf62a53da59f2e7409fdbfee2e4ab6ca9e725e Mon Sep 17 00:00:00 2001 From: bxdxnn <267911624+bxdxnn@users.noreply.github.com> Date: Mon, 23 Mar 2026 19:39:28 +0000 Subject: [PATCH 051/103] Add margin after bullet points --- .../libraries/textcomposer/ElementRichTextEditorStyle.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ElementRichTextEditorStyle.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ElementRichTextEditorStyle.kt index 57f0abefbb..8f6421b654 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ElementRichTextEditorStyle.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ElementRichTextEditorStyle.kt @@ -50,6 +50,9 @@ object ElementRichTextEditorStyle { val codeCornerRadius = 4.dp val codeBorderWidth = 1.dp return RichTextEditorDefaults.style( + bulletList = RichTextEditorDefaults.bulletListStyle( + bulletGapWidth = 8.dp, + ), text = RichTextEditorDefaults.textStyle( color = LocalTextStyle.current.color.takeIf { it.isSpecified } ?: LocalContentColor.current, fontStyle = LocalTextStyle.current.fontStyle, From b578cd1292161a5f0cb1da865857295ee269e5f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 19:58:59 +0000 Subject: [PATCH 052/103] fix(deps): update sqldelight to v2.3.2 --- 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 a3f85b4942..76739c2113 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,7 +45,7 @@ showkase = "1.0.5" # There is some custom logic in `RootFlowNode` that may break because it reuses some Appyx internal APIs. # When upgrading this version, check state restoration still works fine. appyx = "1.7.1" -sqldelight = "2.3.1" +sqldelight = "2.3.2" wysiwyg = "2.41.1" telephoto = "0.18.0" haze = "1.7.2" From 7581d0ecf21e43244b8449463138b61de2a75ede Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Mar 2026 10:15:25 +0100 Subject: [PATCH 053/103] Use formatter for LLS duration --- .../common/ui/LocationConstraintsDialog.kt | 3 - .../impl/share/LiveLocationDuration.kt | 12 +- .../impl/share/ShareLocationPresenter.kt | 12 +- .../location/impl/share/ShareLocationState.kt | 3 +- .../impl/share/ShareLocationStateProvider.kt | 11 +- .../location/impl/share/ShareLocationView.kt | 11 +- .../DefaultShareLocationEntryPointTest.kt | 2 + .../impl/share/ShareLocationPresenterTest.kt | 11 +- .../dateformatter/api/DurationFormatter.kt | 13 ++ .../impl/DefaultDurationFormatter.kt | 69 +++++++++ .../impl/DefaultDurationFormatterTest.kt | 133 ++++++++++++++++++ .../test/FakeDurationFormatter.kt | 19 +++ 12 files changed, 275 insertions(+), 24 deletions(-) create mode 100644 libraries/dateformatter/impl/src/main/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatter.kt create mode 100644 libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatterTest.kt create mode 100644 libraries/dateformatter/test/src/main/kotlin/io/element/android/libraries/dateformatter/test/FakeDurationFormatter.kt diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt index 188f8129f8..95f5129f91 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt @@ -29,21 +29,18 @@ fun LocationConstraintsDialog( onSubmitClick = onRequestPermissions, onDismiss = onDismiss, submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), ) LocationConstraintsDialogState.PermissionDenied -> ConfirmationDialog( content = stringResource(CommonStrings.error_missing_location_auth_android, appName), onSubmitClick = onOpenAppSettings, onDismiss = onDismiss, submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), ) LocationConstraintsDialogState.LocationServiceDisabled -> ConfirmationDialog( content = stringResource(CommonStrings.error_location_service_disabled_android), onSubmitClick = onOpenLocationSettings, onDismiss = onDismiss, submitText = stringResource(CommonStrings.action_continue), - cancelText = stringResource(CommonStrings.action_cancel), ) } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt index e4ecf331f6..6a45ce3def 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/LiveLocationDuration.kt @@ -8,14 +8,8 @@ package io.element.android.features.location.impl.share import kotlin.time.Duration -import kotlin.time.Duration.Companion.hours -import kotlin.time.Duration.Companion.minutes -enum class LiveLocationDuration( +data class LiveLocationDuration( val duration: Duration, - val label: String, -) { - FifteenMinutes(15.minutes, "15 minutes"), - OneHour(1.hours, "1 hour"), - EightHours(8.hours, "8 hours") -} + val formatted: String +) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index 56b7b073d9..10fddf1e50 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -34,6 +34,7 @@ import io.element.android.features.messages.api.MessageComposerContext import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.dateformatter.api.DurationFormatter import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.MatrixClient @@ -43,7 +44,12 @@ import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes + +private val LIVE_LOCATION_DURATIONS = listOf(15.minutes, 1.hours, 8.hours) @AssistedInject class ShareLocationPresenter( @@ -56,6 +62,7 @@ class ShareLocationPresenter( private val buildMeta: BuildMeta, private val featureFlagService: FeatureFlagService, private val client: MatrixClient, + private val durationFormatter: DurationFormatter, ) : Presenter { @AssistedFactory fun interface Factory { @@ -105,7 +112,10 @@ class ShareLocationPresenter( ShareLocationEvent.ShowLiveLocationDurationPicker -> { val constraintsResult = checkLocationConstraints(permissionsState, locationActions) dialogState = if (constraintsResult is LocationConstraintsCheck.Success) { - ShareLocationState.Dialog.LiveLocationDuration + val durations = LIVE_LOCATION_DURATIONS.map { + LiveLocationDuration(duration = it, formatted = durationFormatter.format(it)) + } + ShareLocationState.Dialog.LiveLocationDurations(durations.toImmutableList()) } else { Constraints(constraintsResult.toDialogState()) } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt index 72f94d5b06..8b1f494f1e 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationState.kt @@ -10,6 +10,7 @@ package io.element.android.features.location.impl.share import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.matrix.api.user.MatrixUser +import kotlinx.collections.immutable.ImmutableList data class ShareLocationState( val currentUser: MatrixUser, @@ -23,6 +24,6 @@ data class ShareLocationState( sealed interface Dialog { data object None : Dialog data class Constraints(val state: LocationConstraintsDialogState) : Dialog - data object LiveLocationDuration : Dialog + data class LiveLocationDurations(val durations: ImmutableList) : Dialog } } diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt index efc7fdc8a1..facef74346 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationStateProvider.kt @@ -12,6 +12,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import kotlinx.collections.immutable.persistentListOf +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes private const val APP_NAME = "ApplicationName" @@ -49,7 +52,13 @@ class ShareLocationStateProvider : PreviewParameterProvider hasLocationPermission = true, ), aShareLocationState( - dialogState = ShareLocationState.Dialog.LiveLocationDuration, + dialogState = ShareLocationState.Dialog.LiveLocationDurations( + persistentListOf( + LiveLocationDuration(15.minutes, "15 minutes"), + LiveLocationDuration(1.hours, "1 hour"), + LiveLocationDuration(8.hours, "8 hours"), + ) + ), trackUserPosition = true, hasLocationPermission = true, canShareLiveLocation = true, diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index b463d494dc..4651389212 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -59,6 +59,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.ImmutableList import org.maplibre.compose.camera.CameraMoveReason import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState @@ -83,7 +84,8 @@ fun ShareLocationView( onOpenLocationSettings = { state.eventSink(ShareLocationEvent.OpenLocationSettings) }, onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) }, ) - ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog( + is ShareLocationState.Dialog.LiveLocationDurations -> LiveLocationDurationDialog( + durations = dialogState.durations, onSelectDuration = { duration -> state.eventSink(ShareLocationEvent.StartLiveLocationShare(duration)) context.toast("Not implemented yet!") @@ -252,6 +254,7 @@ private fun ShareLiveLocationItem( @Composable private fun LiveLocationDurationDialog( + durations: ImmutableList, onSelectDuration: (Duration) -> Unit, onDismiss: () -> Unit, ) { @@ -259,14 +262,14 @@ private fun LiveLocationDurationDialog( ListDialog( title = "Choose how long to share your live location.", submitText = stringResource(CommonStrings.action_continue), - onSubmit = { onSelectDuration(LiveLocationDuration.entries[selectedIndex].duration) }, + onSubmit = { onSelectDuration(durations[selectedIndex].duration) }, onDismissRequest = onDismiss, applyPaddingToContents = false, verticalArrangement = Arrangement.Top ) { - itemsIndexed(LiveLocationDuration.entries) { index, duration -> + itemsIndexed(durations) { index, duration -> RadioButtonListItem( - headline = duration.label, + headline = duration.formatted, selected = index == selectedIndex, onSelect = { selectedIndex = index }, compactLayout = true, diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt index 100e660820..edd000e02c 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/DefaultShareLocationEntryPointTest.kt @@ -14,6 +14,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter import io.element.android.features.messages.test.FakeMessageComposerContext +import io.element.android.libraries.dateformatter.test.FakeDurationFormatter import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.test.FakeMatrixClient @@ -46,6 +47,7 @@ class DefaultShareLocationEntryPointTest { buildMeta = aBuildMeta(), featureFlagService = FakeFeatureFlagService(), client = FakeMatrixClient(), + durationFormatter = FakeDurationFormatter(), ) }, analyticsService = FakeAnalyticsService(), diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 125d5036fe..92c27d9f21 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -18,10 +18,10 @@ import io.element.android.features.location.impl.aPermissionsState import io.element.android.features.location.impl.common.actions.FakeLocationActions import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsEvents -import io.element.android.features.location.impl.common.permissions.PermissionsPresenter import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.messages.test.FakeMessageComposerContext +import io.element.android.libraries.dateformatter.test.FakeDurationFormatter import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -54,13 +54,13 @@ class ShareLocationPresenterTest { private val fakeFeatureFlagService = FakeFeatureFlagService() private val fakeMatrixClient = FakeMatrixClient(sessionId = A_USER_ID) + private val durationFormatter = FakeDurationFormatter() + private fun createShareLocationPresenter( joinedRoom: JoinedRoom = FakeJoinedRoom(), locationActions: FakeLocationActions = fakeLocationActions, ): ShareLocationPresenter = ShareLocationPresenter( - permissionsPresenterFactory = object : PermissionsPresenter.Factory { - override fun create(permissions: List): PermissionsPresenter = fakePermissionsPresenter - }, + permissionsPresenterFactory = { fakePermissionsPresenter }, room = joinedRoom, timelineMode = Timeline.Mode.Live, analyticsService = fakeAnalyticsService, @@ -69,6 +69,7 @@ class ShareLocationPresenterTest { buildMeta = fakeBuildMeta, featureFlagService = fakeFeatureFlagService, client = fakeMatrixClient, + durationFormatter = durationFormatter, ) @Test @@ -306,7 +307,7 @@ class ShareLocationPresenterTest { initialState.eventSink(ShareLocationEvent.ShowLiveLocationDurationPicker) val durationDialogState = awaitItem() - assertThat(durationDialogState.dialogState).isEqualTo(ShareLocationState.Dialog.LiveLocationDuration) + assertThat(durationDialogState.dialogState).isInstanceOf(ShareLocationState.Dialog.LiveLocationDurations::class.java) cancelAndIgnoreRemainingEvents() } } diff --git a/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/DurationFormatter.kt b/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/DurationFormatter.kt index 8ecf01c343..ac297d10e9 100644 --- a/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/DurationFormatter.kt +++ b/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/DurationFormatter.kt @@ -11,6 +11,19 @@ package io.element.android.libraries.dateformatter.api import java.util.Locale import kotlin.time.Duration +/** + * Formats a duration in a localized, human-readable way. + * Uses the largest appropriate unit (hours, minutes, or seconds). + * + * Examples (in English): + * - 2 hours 30 minutes → "3 hours" (rounded) + * - 45 minutes → "45 minutes" + * - 30 seconds → "30 seconds" + */ +interface DurationFormatter { + fun format(duration: Duration): String +} + /** * Convert milliseconds to human readable duration. * Hours in 1 digit or more. diff --git a/libraries/dateformatter/impl/src/main/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatter.kt b/libraries/dateformatter/impl/src/main/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatter.kt new file mode 100644 index 0000000000..41a4c66481 --- /dev/null +++ b/libraries/dateformatter/impl/src/main/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatter.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Element Creations 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.dateformatter.impl + +import android.icu.text.MeasureFormat +import android.icu.text.MeasureFormat.FormatWidth +import android.icu.util.Measure +import android.icu.util.MeasureUnit +import android.text.format.DateUtils +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding +import io.element.android.libraries.dateformatter.api.DurationFormatter +import java.util.Locale +import kotlin.time.Duration +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes + +/** + * Formats durations in a localized, human-readable way using Android's MeasureFormat. + * + * Uses WIDE format for readability (e.g., "5 hours", "3 minutes", "10 seconds"). + * Rounds to the nearest unit for cleaner display. + */ +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) +class DefaultDurationFormatter( + localeChangeObserver: LocaleChangeObserver, + locale: Locale, +) : DurationFormatter, LocaleChangeListener { + init { + localeChangeObserver.addListener(this) + } + + // Cache formatter, recreate only on locale change + private var formatter: MeasureFormat = MeasureFormat.getInstance(locale, FormatWidth.WIDE) + + override fun onLocaleChange() { + formatter = MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE) + } + + override fun format(duration: Duration): String { + val millis = duration.inWholeMilliseconds + + return when { + duration >= 1.hours -> { + // Round to nearest hour (add 30 minutes before dividing) + val hours = ((millis + 30 * DateUtils.MINUTE_IN_MILLIS) / DateUtils.HOUR_IN_MILLIS).toInt() + formatter.format(Measure(hours, MeasureUnit.HOUR)) + } + duration >= 1.minutes -> { + // Round to nearest minute (add 30 seconds before dividing) + val minutes = ((millis + 30 * DateUtils.SECOND_IN_MILLIS) / DateUtils.MINUTE_IN_MILLIS).toInt() + formatter.format(Measure(minutes, MeasureUnit.MINUTE)) + } + else -> { + // Round to nearest second (add 500ms before dividing) + val seconds = ((millis + 500) / DateUtils.SECOND_IN_MILLIS).toInt() + formatter.format(Measure(seconds, MeasureUnit.SECOND)) + } + } + } +} diff --git a/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatterTest.kt b/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatterTest.kt new file mode 100644 index 0000000000..3fee5dbb0d --- /dev/null +++ b/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultDurationFormatterTest.kt @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2025 Element Creations 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.dateformatter.impl + +import android.os.Build +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import java.util.Locale +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds + +@RunWith(AndroidJUnit4::class) +@Config(qualifiers = "en", sdk = [Build.VERSION_CODES.TIRAMISU]) +class DefaultDurationFormatterTest { + private fun createDurationFormatter(): DefaultDurationFormatter { + return DefaultDurationFormatter( + localeChangeObserver = {}, + locale = Locale.US, + ) + } + + @Test + fun `test zero duration`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(0.seconds)).isEqualTo("0 seconds") + } + + @Test + fun `test 1 second`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.seconds)).isEqualTo("1 second") + } + + @Test + fun `test 30 seconds`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(30.seconds)).isEqualTo("30 seconds") + } + + @Test + fun `test 59 seconds`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(59.seconds)).isEqualTo("59 seconds") + } + + @Test + fun `test 1 minute`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.minutes)).isEqualTo("1 minute") + } + + @Test + fun `test 1 minute 29 seconds rounds to 1 minute`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.minutes + 29.seconds)).isEqualTo("1 minute") + } + + @Test + fun `test 1 minute 30 seconds rounds to 2 minutes`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.minutes + 30.seconds)).isEqualTo("2 minutes") + } + + @Test + fun `test 45 minutes`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(45.minutes)).isEqualTo("45 minutes") + } + + @Test + fun `test 59 minutes`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(59.minutes)).isEqualTo("59 minutes") + } + + @Test + fun `test 1 hour`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.hours)).isEqualTo("1 hour") + } + + @Test + fun `test 1 hour 29 minutes rounds to 1 hour`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.hours + 29.minutes)).isEqualTo("1 hour") + } + + @Test + fun `test 1 hour 30 minutes rounds to 2 hours`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(1.hours + 30.minutes)).isEqualTo("2 hours") + } + + @Test + fun `test 2 hours 30 minutes rounds to 3 hours`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(2.hours + 30.minutes)).isEqualTo("3 hours") + } + + @Test + fun `test 5 hours`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(5.hours)).isEqualTo("5 hours") + } + + @Test + fun `test 24 hours`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(24.hours)).isEqualTo("24 hours") + } + + @Test + fun `test rounding at seconds threshold - 499ms rounds to 0 seconds`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(499.milliseconds)).isEqualTo("0 seconds") + } + + @Test + fun `test rounding at seconds threshold - 500ms rounds to 1 second`() { + val formatter = createDurationFormatter() + assertThat(formatter.format(500.milliseconds)).isEqualTo("1 second") + } +} diff --git a/libraries/dateformatter/test/src/main/kotlin/io/element/android/libraries/dateformatter/test/FakeDurationFormatter.kt b/libraries/dateformatter/test/src/main/kotlin/io/element/android/libraries/dateformatter/test/FakeDurationFormatter.kt new file mode 100644 index 0000000000..7b5cf038ce --- /dev/null +++ b/libraries/dateformatter/test/src/main/kotlin/io/element/android/libraries/dateformatter/test/FakeDurationFormatter.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Element Creations 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.dateformatter.test + +import io.element.android.libraries.dateformatter.api.DurationFormatter +import kotlin.time.Duration + +class FakeDurationFormatter( + private val formatLambda: (Duration) -> String = { it.toString() }, +) : DurationFormatter { + override fun format(duration: Duration): String { + return formatLambda(duration) + } +} From df6e76776d62528300de893f17271d8230637205 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Mar 2026 11:13:40 +0100 Subject: [PATCH 054/103] Add localazy config for location sharing --- .../location/impl/src/main/res/values-fi/translations.xml | 4 ++++ .../location/impl/src/main/res/values-fr/translations.xml | 4 ++++ features/location/impl/src/main/res/values/localazy.xml | 4 ++++ .../ui-strings/src/main/res/values-fi/translations.xml | 1 - .../ui-strings/src/main/res/values-fr/translations.xml | 1 - libraries/ui-strings/src/main/res/values/localazy.xml | 1 - tools/localazy/config.json | 7 +++++++ 7 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 features/location/impl/src/main/res/values-fi/translations.xml create mode 100644 features/location/impl/src/main/res/values-fr/translations.xml create mode 100644 features/location/impl/src/main/res/values/localazy.xml diff --git a/features/location/impl/src/main/res/values-fi/translations.xml b/features/location/impl/src/main/res/values-fi/translations.xml new file mode 100644 index 0000000000..bc7e84e7b0 --- /dev/null +++ b/features/location/impl/src/main/res/values-fi/translations.xml @@ -0,0 +1,4 @@ + + + "Valitse, kuinka kauan haluat jakaa reaaliaikaisen sijaintisi." + diff --git a/features/location/impl/src/main/res/values-fr/translations.xml b/features/location/impl/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..46689488e1 --- /dev/null +++ b/features/location/impl/src/main/res/values-fr/translations.xml @@ -0,0 +1,4 @@ + + + "Choisissez la durĆ©e pendant laquelle vous partagerez votre position en direct." + diff --git a/features/location/impl/src/main/res/values/localazy.xml b/features/location/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..04538049db --- /dev/null +++ b/features/location/impl/src/main/res/values/localazy.xml @@ -0,0 +1,4 @@ + + + "Choose how long to share your live location." + diff --git a/libraries/ui-strings/src/main/res/values-fi/translations.xml b/libraries/ui-strings/src/main/res/values-fi/translations.xml index e7606fce3e..182f403140 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -496,7 +496,6 @@ Haluatko varmasti jatkaa?" "ViestiƤ ladataan…" "NƤytƤ kaikki" "Keskustelu" - "Valitse, kuinka kauan haluat jakaa reaaliaikaisen sijaintisi." "Jaa sijainti" "Jaa sijaintini" "Avaa Apple Mapsissa" 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 fdc682a67b..1dad21ff65 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -496,7 +496,6 @@ RaisonĀ : %1$s." "Chargement du message…" "Voir tout" "Discussion" - "Choisissez la durĆ©e pendant laquelle vous partagerez votre position en direct." "Partage de position" "Partager ma position" "Ouvrir dans Apple Maps" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index c5258a23c9..98a8aa1862 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -496,7 +496,6 @@ Are you sure you want to continue?" "Loading message…" "View All" "Chat" - "Choose how long to share your live location." "Share location" "Share my location" "Open in Apple Maps" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index d9c5e088e1..d3e44b7c08 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -409,6 +409,13 @@ "screen\\.security_and_privacy\\..*", "screen\\.manage_authorized_spaces\\..*" ] + }, + { + "name" : ":features:location:impl", + "includeRegex" : [ + "screen\\.share_location\\..*", + "screen\\.view_location\\..*" + ] } ] } From 8910d20ae45c08086b631684f9aa473bdd2d6b7e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Mar 2026 11:22:51 +0100 Subject: [PATCH 055/103] Remove hardcoded strings --- .../features/location/impl/share/ShareLocationView.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt index 4651389212..1e163f417d 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt @@ -37,6 +37,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.location.api.Location import io.element.android.features.location.api.internal.centerBottomEdge +import io.element.android.features.location.impl.R import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton @@ -242,7 +243,7 @@ private fun ShareLiveLocationItem( ) { ListItem( headlineContent = { - Text("Share live location") + Text(stringResource(CommonStrings.action_share_live_location)) }, onClick = onClick, leadingContent = ListItemContent.Icon( @@ -260,7 +261,7 @@ private fun LiveLocationDurationDialog( ) { var selectedIndex by remember { mutableIntStateOf(0) } ListDialog( - title = "Choose how long to share your live location.", + title = stringResource(R.string.screen_share_location_live_location_duration_picker_title), submitText = stringResource(CommonStrings.action_continue), onSubmit = { onSelectDuration(durations[selectedIndex].duration) }, onDismissRequest = onDismiss, From 7a4641c422279279df2d8eca8cfbb9e20e890d81 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Mar 2026 12:15:14 +0100 Subject: [PATCH 056/103] Fix warning --- .../matrix/impl/timeline/item/event/EventMessageMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt index d89d2766eb..e382bce8db 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt @@ -117,7 +117,7 @@ class EventMessageMapper { body = type.content.body, geoUri = type.content.geoUri, description = type.content.description, - assetType = type.content.asset?.into() + assetType = type.content.asset.into() ) } is MessageType.Other -> { From 7912db2ce84e921a6c0676b27d825788ab3094b3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 11:14:16 +0100 Subject: [PATCH 057/103] Space header: change font of info to fontBodyMdRegular and icon size to 16. See #6364 --- .../android/libraries/matrix/ui/components/SpaceInfoRow.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f83b46a3d7..997fbbee59 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 @@ -48,7 +48,7 @@ fun SpaceInfoRow( ) { if (iconVector != null) { Icon( - modifier = Modifier.size(20.dp), + modifier = Modifier.size(16.dp), imageVector = iconVector, contentDescription = null, tint = ElementTheme.colors.iconTertiary, @@ -61,7 +61,7 @@ fun SpaceInfoRow( } Text( text = text, - style = ElementTheme.typography.fontBodyLgRegular, + style = ElementTheme.typography.fontBodyMdRegular, color = ElementTheme.colors.textSecondary, textAlign = TextAlign.Center, ) From 637df0a228f890c222c041560a1578cf76bc00b2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 11:31:14 +0100 Subject: [PATCH 058/103] Edit room/space detail: change avatar size to 64 and adapt edit icon ratio. See #6364 --- .../features/roomdetailsedit/impl/RoomDetailsEditView.kt | 3 +++ .../libraries/designsystem/components/avatar/AvatarSize.kt | 2 +- .../libraries/matrix/ui/components/AvatarPickerView.kt | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt index 3fd9daef3e..252670630f 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt @@ -51,6 +51,9 @@ import io.element.android.libraries.matrix.ui.components.AvatarPickerView import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.ui.strings.CommonStrings +/** + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2204-37063 + */ @Composable fun RoomDetailsEditView( state: RoomDetailsEditState, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 8407445394..8565b0575f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -46,7 +46,7 @@ enum class AvatarSize(val dp: Dp) { RoomInviteItem(52.dp), InviteSender(16.dp), - EditRoomDetails(68.dp), + EditRoomDetails(64.dp), RoomListManageUser(96.dp), NotificationsOptIn(32.dp), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt index 68a346ab84..89f980ab99 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt @@ -113,7 +113,7 @@ fun AvatarPickerView( }, y = size.height - editIconRadius.toPx(), ), - radius = editIconRadius.toPx() * 1.2f, + radius = editIconRadius.toPx() * 1.35f, blendMode = BlendMode.Clear, ) } @@ -143,7 +143,7 @@ fun AvatarPickerView( ) if (enabled) { OverlayEditButton( - editButtonSize = state.avatarData.size.dp * 0.44f, + editButtonSize = state.avatarData.size.dp * 30 / 64f, onClick = onClick, interactionSource = interactionSource ) @@ -195,7 +195,7 @@ private fun BoxScope.OverlayEditButton( contentAlignment = Alignment.Center, ) { Icon( - modifier = Modifier.size(editButtonSize * 0.66f), + modifier = Modifier.size(editButtonSize * 24 / 30f), imageVector = CompoundIcons.Edit(), contentDescription = null, ) From 805eaf631de6c70c61b11aa2f0b4fd66139b6b25 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 12:51:57 +0100 Subject: [PATCH 059/103] We want an icon size of 20 when the avatar size is 64. --- .../android/libraries/matrix/ui/components/AvatarPickerView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt index 89f980ab99..b1dff2c981 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt @@ -195,7 +195,7 @@ private fun BoxScope.OverlayEditButton( contentAlignment = Alignment.Center, ) { Icon( - modifier = Modifier.size(editButtonSize * 24 / 30f), + modifier = Modifier.size(editButtonSize * 20 / 30f), imageVector = CompoundIcons.Edit(), contentDescription = null, ) From 19d19b4b58ed80984b1400256568793fa3814eab Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Mar 2026 12:11:19 +0000 Subject: [PATCH 060/103] Update screenshots --- ...eateroom.impl.configureroom_ConfigureRoomViewDark_0_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_1_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_2_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_3_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_4_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_5_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_6_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_7_en.png | 4 ++-- ...eateroom.impl.configureroom_ConfigureRoomViewDark_8_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_0_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_1_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_2_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_3_en.png | 2 +- ...ateroom.impl.configureroom_ConfigureRoomViewLight_4_en.png | 2 +- ...ateroom.impl.configureroom_ConfigureRoomViewLight_5_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_6_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_7_en.png | 4 ++-- ...ateroom.impl.configureroom_ConfigureRoomViewLight_8_en.png | 4 ++-- .../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_Day_2_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Night_0_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Night_1_en.png | 4 ++-- .../features.home.impl.spaces_HomeSpacesView_Night_2_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 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_0_en.png | 4 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_1_en.png | 4 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_2_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_0_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_1_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_2_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_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 | 4 ++-- .../images/features.space.impl.root_SpaceView_Day_5_en.png | 4 ++-- .../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 | 4 ++-- .../images/features.space.impl.root_SpaceView_Night_5_en.png | 4 ++-- ...raries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png | 4 ++-- ...ries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png | 4 ++-- ...ries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png | 4 ++-- ...es.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png | 4 ++-- ...braries.matrix.ui.components_AvatarPickerView_Day_0_en.png | 4 ++-- ...aries.matrix.ui.components_AvatarPickerView_Night_0_en.png | 4 ++-- ...aries.matrix.ui.components_OrganizationHeader_Day_0_en.png | 4 ++-- ...ies.matrix.ui.components_OrganizationHeader_Night_0_en.png | 4 ++-- ...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 ++-- 80 files changed, 158 insertions(+), 158 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png index e6d7d642c4..13a1a88a4c 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c04d4a82a3c99ad51ebb98ba01f84bb99682c0f0a2fc7e37f8f475b420008d08 -size 29419 +oid sha256:cf9aa6f47084124e7c774ae78bc98404d960805bb1338784f3641251e33ac7c6 +size 29426 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png index 6b87589f55..2e3058ac63 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ee76b66215dc883a7caa499031713ff1bf9bbe9108ae75e010230f9a10d5564 -size 34088 +oid sha256:0d40447ece02c06d429d52138550c73e559f89dfd99f6dff7a92cfc3103f2dbe +size 34093 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png index 2a7005fcb2..a581a42dfd 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:379cd97eb39c693a22f362b065b28be829065620cd46a1ac86bdda1ae96e07e0 -size 41537 +oid sha256:654d8e0acd3b3bbfb856414b5e5ca5615f3febacd8bebaa9af5a1e4d96c5d035 +size 41543 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png index 7f6f01c0b6..33c4f82363 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e91d96e6399867fd1fd18053318067d52663c59f5d4f3c8b0bbbd74fbaed450 -size 42508 +oid sha256:ea98589cd86e69ae6d57566b205b4dab70f5f4b5c8b0fee09c7e690cafa7f914 +size 42514 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png index b6d14bf7ac..7600487323 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adc7703893dcdaf363d823ae3806622b0945adb49eda895aed2687f24a9208f2 -size 44221 +oid sha256:37ffab3c3805f0bdafaca9035af6e4f706286f45a05a761ba7e7c160d45463c1 +size 44226 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png index 2a7005fcb2..a581a42dfd 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:379cd97eb39c693a22f362b065b28be829065620cd46a1ac86bdda1ae96e07e0 -size 41537 +oid sha256:654d8e0acd3b3bbfb856414b5e5ca5615f3febacd8bebaa9af5a1e4d96c5d035 +size 41543 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png index abcdf4599b..05a54538a4 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08fdc74dc7a84894c7c44d2ed8d0dab8a39e3d1f0bd9d5ab0c40c334d3fb95e3 -size 42473 +oid sha256:c20f293ba37e9af3e9f045de2ff1746af5e265d5dcf5bce5dc396da5c29387a6 +size 42482 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en.png index d4b40305f3..5ff5af29b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:785e9c2d9d7760ed98d7c33a56dd5778c3c2c652ee62675fda8e22c0b7aec1e5 -size 37453 +oid sha256:fea7e63fd1d31db6500c4b110b9c05190da7b7201e1029177f8b5a61e728e100 +size 37458 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en.png index 590d4d7489..e51dd98b4f 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d2125380275b921562692b6308aa8086682e45443edf235c5f06916c77aed76 -size 40418 +oid sha256:edc093b514b7e648d176a17b0c368fbed82e9c46d3f584fdb9c6094a6e5aba55 +size 40420 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png index 505f44874e..4dd2b02ce3 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1374e31224ac28a10b25f9b4f7fe1c5bfd321b2d3f71f847cbd9f446dc988546 -size 30468 +oid sha256:7e4dfa9c766681c750383863450aff0052f3083d495fcea1be74446ceed1cc4b +size 30462 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png index 0e1efea045..79155ebbfd 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f086a534df766b627a3b17194c053b49215fecb2887a02eb4e9120fca8ada3d6 -size 35330 +oid sha256:49309d3b55bf7a4313ab100d54f2d13b741b5bace7fec7d03e8e30765d8e100b +size 35329 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png index 5694c49a81..5baf7f75b8 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:029abfce9e6ee628296c7edf48d1d437c9273225101b2327744982ea31b68521 -size 43122 +oid sha256:ea38acc7ef6fb8307b83453eae80ec7c3154a80d0591c4f1fc1a87aa581a7926 +size 43124 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png index fe1ba43cce..920269d44d 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a100d8b0987fe7c0fb5ec28f8e4182b57d50992c779520eb22d09ac6ff8bf979 +oid sha256:7fd71e26763fb648a7b6ac898f2b354056354d1deee3d3712786a0c36e0cf476 size 44168 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png index 046375e9db..65bd6527c1 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2dcb3b3487ce7ff3a8fab6cc6dbba7868d096883830d8cb6c3632151dcd84b56 +oid sha256:7d355371ce78c9a78900a6d76899289844c687b794c2afe127580a7c50b25935 size 45949 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png index 5694c49a81..5baf7f75b8 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:029abfce9e6ee628296c7edf48d1d437c9273225101b2327744982ea31b68521 -size 43122 +oid sha256:ea38acc7ef6fb8307b83453eae80ec7c3154a80d0591c4f1fc1a87aa581a7926 +size 43124 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png index d31293ae15..875f4a71a3 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5259600e107074fc9658f33a0861b7ffd5fc385c2f60f98334b2e91765534c95 -size 44213 +oid sha256:1c73b89404caa0fda5233c7dfed5810276a5cb1c1efd5843484b80c7f859b99a +size 44209 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en.png index d8d9f54a9a..27b3f41f26 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b92a72ae6b5976b728901c363ac14c04905a5399cf6be5542a7eb33e5fa6e0cd -size 38888 +oid sha256:005c6520e884641ca1ca4e1248627937806328fc4ae527b811c65ee933a5616e +size 38889 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en.png index 9de756fa9c..c29181ca85 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9495c93e50452de78efc30a041cf834150a166b0690dd3caee9ccc4565f68241 -size 42063 +oid sha256:4fac6f85109de1b6beb4cff51a91dec8e34ed8ed50820829b63584226e611d5d +size 42064 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 e91dd8db4d..526bd69d4e 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:f3ac57efcab393ce13794dde2ad7e0d60757c0ef7fd0b09ff0a3c338de9a9edd -size 85467 +oid sha256:35c1709b912da1102a50aaa4f8470cbf05a75b03669aec51b90354ccb2b09ba9 +size 85336 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 de0717ece9..de86c4285d 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:f0567c1fe44efb4f9e188252a6840c228eb03e8d7954c95b79c693ac31451cd2 -size 38840 +oid sha256:2d69d687090971ab7e9b87f959521109fbed48413ef217e1be3da8d7d985038b +size 38751 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png index de0717ece9..de86c4285d 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0567c1fe44efb4f9e188252a6840c228eb03e8d7954c95b79c693ac31451cd2 -size 38840 +oid sha256:2d69d687090971ab7e9b87f959521109fbed48413ef217e1be3da8d7d985038b +size 38751 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 b27caf0acf..0b5629c139 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:0f8a54913bd0c207088cec3c0fff9bcab4dca084884493a32a615fa728c40625 -size 83659 +oid sha256:2f60372df2ed22a4c52624e16324f7da1f6000eafdd519f84d42a29acec016ee +size 83600 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 950cf73f60..07e9ef1e28 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:949b1843a373b86fde0bb5a0a0637f938e87aeb3d36b8c146052e99874dfb4dd -size 37667 +oid sha256:d2a6a7f3188eb9635ade7c0bbc2239257cfbe3166f4a6fb7917a1e5578f51d9e +size 37436 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png index 950cf73f60..07e9ef1e28 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:949b1843a373b86fde0bb5a0a0637f938e87aeb3d36b8c146052e99874dfb4dd -size 37667 +oid sha256:d2a6a7f3188eb9635ade7c0bbc2239257cfbe3166f4a6fb7917a1e5578f51d9e +size 37436 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 beb2054ef2..c33ecadd3d 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:303d13645d55db4f9dcb31d68e49d21254778c500daa887694a6d402735ceac2 -size 57175 +oid sha256:e64f044d19a709056de64976c6902baba7821885f35cd88873d5462fd52c3e4c +size 57343 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 01f74fdbc5..c2dc739e38 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:f38bf5504ece28cfe2bdaf5e958ecf8af30a1a3e97b3b2d9c43924c362673402 -size 52181 +oid sha256:1d923c6e3503af723269dbe5c03f1024e7e3fb6ba746fb979f7735c0ad3b8e32 +size 52322 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 f6fd22402b..fd96e55b43 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:d5a1e1666e42d8d70c978e36db2e4b09c1eae52e625622f10aa3d4be2a26d8c3 -size 34940 +oid sha256:9b65479f88eeda454ea14ca7d77a0a61b7c9ff219d4dee6ce6567fbff6b56a5e +size 34631 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 a7839e77fa..cb2f201014 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:68694cdbb914ddac55745505f628d9cbccd01260cc042af16b02465aef068ba2 -size 34427 +oid sha256:b9a0a40ee3125a292e31024d6e653ac289841403266830339efe40a183f7d4c1 +size 34174 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png index cd629ae45f..e3a8861914 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8090f48828c00e9503b9c1d8cf2d25bee2cd0dc212893b233d16e48f63024ad9 -size 21590 +oid sha256:9d5a1632a25fc84bc9c6df9c1c06e9120445428003ddb753565c7887d3e71a74 +size 21847 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png index 0aacefeee3..e680a887e5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53095caca53a83fee3b8189733744b9f9025fb77e9781c7d81c7396d190162ec -size 63152 +oid sha256:4ace8ec66513954fec104f6e2eb1745353b1e6eb417b27137416de057032fc33 +size 61896 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png index a97b7b5e7d..4870b36647 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c62d879f9145956fb00cc9160fb371dc38396326d3539918a453a068a96c2578 -size 30252 +oid sha256:1d410125b5f6a0dd5865f0a0d05f5a88a8fa6651cffde717637cf671ac348067 +size 30405 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png index af681bed4b..1fdbdbae4a 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0316a59f6e64c2f019941fcbc91100ba0723763a3206a7b133475041f8ae40a -size 21765 +oid sha256:326bbf9055be0fcf5199e3841e71cab10c16bbf9d1762ba30f054ecfcc453ec7 +size 22007 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png index 7d8d140e7a..d7a12e749e 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b20a582075b176bbc4ed43727c7ee1c492bc10049d8697fb01d66e74c63e8d3 -size 62101 +oid sha256:a49d67f69827a414243a5d2ee82dc7202fd6b324ba66c43822f82a2249120a3d +size 60631 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png index c040b551c2..c6be9a691a 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8042eb469d5d472c65713e16aefe8aae28423a6db310eb1416f12370eff8079 -size 29442 +oid sha256:a44fb8fb3906a05277b1702aa81ce6b5674539624067019626a6c2daebf7edb2 +size 29638 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png index 0aebc57737..89c8f402b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2305e3cf0adb93983a666216f8cbfdd1472417ad50027a778393713817d26a26 -size 27953 +oid sha256:4c2a3c20783c325f8713968cd3c4d801d9cee9b29b5d785e5b740bbf3801e72e +size 27871 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png index 7a79af6aa3..b0c5e5058e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5bff337898c06fcaee56cd16dc99355b04b3263cb120874f8ba0ef4d83ca060 -size 21703 +oid sha256:d3a4401f3b9ae9a13e455c66503b5acc7673f1489f2bed147832fbcb8258f370 +size 21717 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png index 20c08e39e8..e688484979 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e075cfc4eb49a633af66630da7e90f6901f1ee56981d64a890b1136dc33a6388 -size 29373 +oid sha256:aef2d95eaa65345bb0957a30ae86f5794d5d6a6e09d8108eadd1d78d67d9fde9 +size 29262 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png index 50f58c51bd..dc6ab73909 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9bd49a06d4771b906fe053e274c32e9e69723d1f1610e4697a2961c880b5a9e6 -size 50810 +oid sha256:019539b32a13702d3983ca5b7bb682b2dfe9d578e5eb8dbcb5be9243faa08627 +size 47531 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png index 1d11a70c3b..11e42a8678 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:079e9546687a722023859f5ed08e58cbccf4c8c914695276330045617ad066db -size 47949 +oid sha256:6cfbd1da60262d20c2ea316105879b2fb561d9821fbea402e131c1f029513fc8 +size 44791 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png index b6c1179505..b148f83300 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:658f129a4bff6bf2df9d43cbbf49f8010582950258a066ce6d661e69f59eb121 -size 28013 +oid sha256:3c02ee5dbd57bcd4605e4e8fb650684b4766b68364d8252dda2783f7a663eccd +size 27934 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png index 939e49b894..55b9aef9e8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a68e4455a825e96d2b9d64e5bdf76bbbc87dc215348f9b7d8d5c503f147089b -size 26068 +oid sha256:4e5b8edf83eeeea54b8bc6208d0be4eb3cc9e3506409e0645eda4c3b28eb11d0 +size 25937 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png index 92b536aa7b..771ade2cfb 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b61b245117e58eb7b7bd1c10bd7d75b1ed30f3aa80b26cc1a4ef4f0e48c70bc -size 24864 +oid sha256:fa981dcbdc98e7e8b7d15be7055c2285326ac27c8c49f5487bcddb00f79d687a +size 24933 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png index 1dad39f918..e2c1180058 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b84017e195f8e117b460387144ce5ac55522bd62839c8ca5f59d657a6f672a63 -size 26045 +oid sha256:c134a2a60c7ad1b5d84dade390ad435fdc25290f97daad8da442ee47867afd6d +size 26025 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png index 1cc0801715..421037c3d0 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12312b5c8987fdb2328cd81b8a6a831d83191794346d48e2ab5f8940cb8ba7ce -size 28948 +oid sha256:d04782b64e26a5013cfc5f5f1be217a51d919a1833f365b67f60f57ef926419c +size 29101 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png index 3f2b877106..1925a66cd9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68edaca4978294e4dc361e4aca5656401da342ade4249d098cd5e63f3dd34444 -size 27204 +oid sha256:74648fccd925a279ce090251b931bc5845e305fd0e1262f6e424b7d58b2fd342 +size 27290 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png index 0dc7086d85..24f05a2689 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11143b6cac2bc3159a53efb0db1638343f0595917ac1077818813693cf766b32 -size 21311 +oid sha256:82e8e8d0cc0dbde32d0de399b5a9e3ae4d2e0e6366ba70416aa852ac348464e3 +size 21359 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png index ef14789f1c..e77e4b00c2 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df64c0479b09e64ab64c6201db972490763606b6a2a409d1beb5dbb237131e6a -size 28772 +oid sha256:f235b2be28c26a4d12fc67fa0fb791add8710f34d4efcd452dce7c3c7ffe50da +size 28765 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png index 558f8a074b..7f61a28ce8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c47caf5847c6a3bcc4242e4d5df1e5b12a2570e264aaeb7771fd78ec3195138 -size 49343 +oid sha256:b76fbebf6bb05c4dd365e9bb4da5fbc97b00029333d378bef0cc0bcc9a38cbfd +size 46251 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png index 8e75cc2161..ee7f0b57b8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cbf8b1fa588108daeb18ff713a4cccd2750d2e49c76d0fafec19273531c6983 -size 47074 +oid sha256:b6dfe47955218be4322b6a4ef18631d6b286e0dee38ed7017706fa30e82d9c83 +size 43633 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png index 23a1e3342e..15db2ba218 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d82e60104ef09cc5c0751b913aa33e60da584264fae59b73d38614ea00c8a80 -size 27254 +oid sha256:01149ef85301bd448d9fedaa4d2d7dda6f9ed5392d1af1763dc9aae16c87c000 +size 27261 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png index 4821092f88..bbb362f9a7 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97eec12d7b4669cedc42a9de07dbfcb7aff1bb41ddef4f69a82881900b9f50f1 -size 25253 +oid sha256:60ad790a2a4131d9e833585746787a9f4b182b89b836327c4861dc8121e73f25 +size 25359 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png index 22f8047106..95b23bf68b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:029774c8659b0928a45d4b03c47b19ae5532adf77a97a37974721ac25a89d714 -size 24263 +oid sha256:e37b19634d2e801d4e31fb826e87286dfe1333762e043fbb6c96910234dfdc11 +size 24303 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png index 99211541ab..ff3c793fca 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c3f6164cc6de13c1ac92d1b0bb1cdb3ab2f785d3f42660fb3b12069da892e6e -size 24671 +oid sha256:368fb87d29e66245a70bf83cd7a0b422c6bf760e6634dac00ab633d1316ff4fb +size 24582 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png index 3671f053e8..84e45f955c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ca5770f0d97d4ce5936c3ed40ee98874a19f4efcbd0dddbe0209046f1036e0e -size 27583 +oid sha256:a751079af9e755ba5858176c81e49178c7141bd977f627dd21e1e8e4fef3caa9 +size 27632 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 baa071d995..bd95e60ce0 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:deb53bb9c200815d92744962dbd4c512e982acbb1ee1f7f5049c60961dac69b3 -size 46859 +oid sha256:73608be44121b6125f14e3186ee533a5e479e30124e4276d342a25b476c00fb7 +size 46960 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 87b16bb636..02756acf7b 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:5848d60e57866920c956603d9a7b73ebde571aa410ff8fc4f423478d1a601edd -size 46984 +oid sha256:6ea33f7c49c55c81f976111bf79bdee21eb58f3394c8135a0324f6a503dc6fad +size 47044 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 6a0780e6f8..cf42cff8c7 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:17f534cedbd3aa614327e66db670e4015a0b241e7c764b4654cc2b537a66bad9 -size 48837 +oid sha256:ed108284075a1fc2523ac38d63dbff3176dbeb97942995d4b83aa4f0bc3de240 +size 48636 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 057c499a3b..dc324f5b6f 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:2bc7d4ed3af1798332d32494ff810ca0b2a3405dc1aa4c14235a9ebefcca2a2b -size 59450 +oid sha256:cb31f13ac29f7ebbbe18d2314bfaccfd20f87c308edda618ba36a6f968e2fe33 +size 59929 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 index 52291b098e..462cc991f4 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be63f80b133292a6d998fc7786f3a885af188ec63e50776dc42d3c794c97c04f -size 60116 +oid sha256:1ddc1a68ff028108928942a2ceb6df4caa3ce4322bea836b409e9a7ddf991194 +size 60567 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 index 0d2970f168..34300310ab 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c6e4ac872b497e115985a4d9535c3720d3d9189537cfffcd3f3b30033db636b -size 57156 +oid sha256:0322da022d57cbd3b167f939d00bffdba69758c6508256f1251826cf5621b18b +size 56970 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 32d7763fb7..f9e70f5c88 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:e0ee7e4717d580472984c27b52edbc94e3c11d414df2e1921338e293f037cf10 -size 45272 +oid sha256:e9b3bc80e39daf9809464a771089e431be993e8faba40431784990f61e7c2a4f +size 45233 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 3b490f8031..e6e4b0cec0 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:00e4005c9b8c964169657d4866ba4525683802f60fad963f9937c42a3af3aac9 -size 45378 +oid sha256:aa6f0b045b83a4bd8b1f2ff9727964ec82ce7781f575ee6c1e306eeecd7da63b +size 45319 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 5fa72cf478..3bd02250a2 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:6ba87e5bdf17fa152aa19d7b82375f72d94921befc193e3a2d16789c95184670 -size 47109 +oid sha256:471ed0a332d92a41a82536c5ac2204909391730b811d44f54d8b308fb03447f9 +size 46791 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 8b2c2e4135..15f3619b7d 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:8c68a6a0247bcbcca56f1a0d93b888bae5a7ac23edd86bea2fa764e852429cbd -size 57656 +oid sha256:325ef5fb725ea61c382eec96668b4fbfca9eee08e1503eb72e298b4d62d684e1 +size 58256 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 index fc950a4598..51d1ddc9f5 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d51605bbf9d50ec062ad631f7e59b4df2ad33b5c0a5802a9213222b3831c93b1 -size 58233 +oid sha256:fd73b018c8fd459eab5849c942e4f992357abbb4d0e0ba1cc5847e0985ff335d +size 58836 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 index e009829a2a..daaaf7a44b 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70898c5044adbc7bb5a318bf218a551daeb62390d767eb0457774900f52d401a -size 55072 +oid sha256:57cd29c2032d425f94551a0fda528ec5dbaa467900f6235fb40aa6009ee22bec +size 54897 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png index e6bb90a131..e080edf472 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5726a43d99a6c7b12b89280eec24a35015800bba0b6311d25dfa5b0657436bf2 -size 218639 +oid sha256:b39e11e7b301b4aace05efbc4cbcf5c9273e0a946b9982fcaeeb2aeebedc1146 +size 207976 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png index 7c54664343..e8584bb160 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37e3e9bfe4305f741b897430b3fdc3b8a8b0f80c0877589fad69743750d530dc -size 213898 +oid sha256:55bfc5e3f65bc8e31b32bffb133f101d624c873ae0976c5108a1b5c8543d14af +size 203310 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png index 02fe68eb49..d1abfc3a7d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aefedd3be6c0b57cebd07f7f008a7d46c1b6c9e35233047cdae9056d64e1be3a -size 184665 +oid sha256:68d55addf93d6aa72f5f3752ff41016bd106b2ce552f06c0f2e4d21cd536313c +size 171905 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png index 4a61d15a00..dbae2173ee 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14c46d22d1b75881d26a0eaf88ef2e551f5e9b9a2a146f0255e93c0540562c73 -size 181483 +oid sha256:fa60d59d4beb4a11795897e112be156ce58d4347d039a1a163df519819c880ab +size 168619 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png index b85a0d53dc..68c57c8de1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b67f065531858f105c25d07a7943ea0e32d6294fad408c0b7f1fbe062367115e -size 182058 +oid sha256:60e9a853870a1f8e405619f3ed156f1eb122e08a5d2c102d5c16566e6911398a +size 170340 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png index 7b74856c1d..442d12e9bb 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f41b7f0ce1524f287f31376dfb91d8c54d91ea3ad7dac7493f0168f3324c5d14 -size 179341 +oid sha256:9b219ab086da6c8b7b72f19da8a7c728ee6ebeaacde7ef749a1586289b2ac6e9 +size 166821 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Day_0_en.png index abb750e1c6..f151ea1f46 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcee923854778a24a3043060aca26ea0a408b23facb4b4694798907e22b7c500 -size 42033 +oid sha256:d19701e98fb988c19f7c4862f48ba192c4b5faf400c224a013189e3f2c489f78 +size 41519 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Night_0_en.png index 14f7906cb1..d0088f67ec 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_OrganizationHeader_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10cfbc2475a36f3f75973113b8dc1282d19ee7dccaa502a5dee5c95c4901842f -size 41513 +oid sha256:9ca98f8662d66b7d9c4484e5c5b0a6b9c9fa5ea1cdd7e430dbc071249390287d +size 40957 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 e8cf990c8f..3caed99b5a 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:de4639ba342b268d5de55627a4d17f8d84174f2b9ae83e3a1543738fd20d0196 -size 17146 +oid sha256:53ec492b0a46d3add165e01c7ce540f304574791d10232a825e28cd15ae22248 +size 16903 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 451b5aa2fd..c653ffd3fe 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:23e90312791319d6318cf5971235be55531baf13da7e7c969bd15774d3140df6 -size 16161 +oid sha256:938b51a3e4e4466056da464fabd34066b716fbf55622b179f799181ff900819f +size 15978 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 8a07b19458..f1bd04835c 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:ddd8149f9d7cb4867bdf5f12276d778d2ed56963051961e949f4feb470308fc4 -size 63636 +oid sha256:7853b79eda8a4b82cc49d553f78f545af62bc44b708a20a5bb5e4582ed07bc22 +size 63262 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 0001b03170..9eba778594 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:6794c0d21a221b47c9c808339e7eae1195af9504d4ea3f68bede59f3d77cf1c4 -size 62497 +oid sha256:7daff199310c41900d0ca650f38ad2561c8db8542a4d48161a5a88f7fe976318 +size 61899 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 6e4e1a9f6e..10ef509960 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:d3ac61279d8534d3ce201f175563ac9cffc533bd89c9e183666d6aa2d04dbbaa -size 20424 +oid sha256:8be1c1e7f13fa92b9d435b067d6cfe60fff26c79fc2eaf0277593fb26a92dd68 +size 18248 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 f791229807..0105bfaaf3 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:3fe106b1528e558785aaff67c8a7c4531c95f1354de65c1337d2414dd4650f0d -size 19357 +oid sha256:302d45fff4a8c7efe00656ba1f001e6991dcd18883cd06d752b350e1dd4682f7 +size 17129 From 7f6eec3a8feaf576507de5161dcc6b165a778dad Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Mar 2026 12:54:32 +0000 Subject: [PATCH 061/103] Update screenshots --- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_8_en.png | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png index 63fee25873..f7398ae396 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:331388711afc99265e651897c04df501f2de777fd0c8e4b084f67fce2a2a1c94 -size 66937 +oid sha256:15256a6b4d1fe8e52080b9726cde401944cc6941f7527db1d18484c86ec88023 +size 66699 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png index 8b189dd1c7..9bfed4fc61 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2bd8f39629ae22d9226f9d759b73a1db9d1d53a80923c835bef6bd403e45e737 -size 64060 +oid sha256:d7c95c91b7c6b04f2851df6a64de1b10c7338a4d46921a90037fe50cd7d49262 +size 63957 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png index fd37f7ae83..8e397b024e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de8ffda35666fc34ba5521673af2318ba162a442574005b5062afc17172f4bf5 -size 67414 +oid sha256:27c823be03e6721a4034cdc4827a4d3dd34ac3e9d567651a8ce125cef435b57e +size 67151 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png index 203dcc6280..0654617bd7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0514f7ceb74b446203f36cf6af6b1da3e8f0a55f7e636a0341b2703201d6390e -size 64529 +oid sha256:947ddd34efb97e8baad91a1c2865105190a7be599327a271db0466f4a86bf092 +size 64326 From 3b078654a237fa1273b82c5d9b1965bb4ad45eec Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 15:04:55 +0100 Subject: [PATCH 062/103] Iterate design on EditUserProfileView --- .../preferences/impl/user/editprofile/EditUserProfileView.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt index e997f08d65..774dcedae0 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt @@ -53,6 +53,9 @@ import io.element.android.libraries.matrix.ui.components.AvatarPickerView import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.ui.strings.CommonStrings +/** + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=3182-36115&t=U1vS3px9HzlzWYd7-4 + */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun EditUserProfileView( @@ -125,7 +128,7 @@ fun EditUserProfileView( style = ElementTheme.typography.fontBodyLgRegular, textAlign = TextAlign.Center, ) - Spacer(modifier = Modifier.height(40.dp)) + Spacer(modifier = Modifier.height(32.dp)) TextField( label = stringResource(R.string.screen_edit_profile_display_name), value = state.displayName, From af2bf8435b887dc1e39e76eac8777bc3730c4c0e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 15:06:15 +0100 Subject: [PATCH 063/103] AvatarPickerView: ensure the pencil icon always has the same size and improve the preview. --- .../matrix/ui/components/AvatarPickerView.kt | 176 +++++++----------- 1 file changed, 65 insertions(+), 111 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt index b1dff2c981..e743a2447c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt @@ -61,8 +61,16 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.CommonStrings +private val editIconContainerSize = 30.dp +private val editIconContainerRadius = editIconContainerSize / 2 +private val editIconContainerPadding = 4.dp +private val editIconSize = 20.dp +private val editIconOffset = 8.dp + /** - * Avatar picker view, based on https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=5918-97417&t=JYDQysgjS33AZb74-4 + * Avatar picker view. + * + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1949-1384 * * It takes a [state], which can be [AvatarPickerState.Pick] for displaying the 'pick avatar' button, or [AvatarPickerState.Selected] when an avatar has * already been selected. @@ -96,7 +104,6 @@ fun AvatarPickerView( fun eraseBackgroundModifier( parentWidth: Dp, - editIconRadius: Dp, ) = Modifier .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen @@ -107,13 +114,13 @@ fun AvatarPickerView( color = Color.Black, center = Offset( x = if (layoutDirection == LayoutDirection.Ltr) { - parentWidth.toPx() - editIconRadius.toPx() * 0.48f + (parentWidth - editIconContainerRadius + editIconOffset).toPx() } else { - editIconRadius.toPx() * 0.48f + (editIconContainerRadius - editIconOffset).toPx() }, - y = size.height - editIconRadius.toPx(), + y = size.height - editIconContainerRadius.toPx(), ), - radius = editIconRadius.toPx() * 1.35f, + radius = (editIconContainerRadius + editIconContainerPadding).toPx(), blendMode = BlendMode.Clear, ) } @@ -132,7 +139,7 @@ fun AvatarPickerView( is AvatarPickerState.Selected -> { Box(modifier = modifier) { val backgroundModifier = if (enabled) { - eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f) + eraseBackgroundModifier(state.avatarData.size.dp) } else { Modifier } @@ -143,7 +150,6 @@ fun AvatarPickerView( ) if (enabled) { OverlayEditButton( - editButtonSize = state.avatarData.size.dp * 30 / 64f, onClick = onClick, interactionSource = interactionSource ) @@ -179,15 +185,14 @@ private fun PickButton( @Composable private fun BoxScope.OverlayEditButton( - editButtonSize: Dp, onClick: () -> Unit, interactionSource: MutableInteractionSource ) { Box( modifier = Modifier .align(Alignment.BottomEnd) - .size(editButtonSize) - .offset(x = editButtonSize * 0.266f) + .size(editIconContainerSize) + .offset(x = editIconOffset) .clip(CircleShape) .clickable(interactionSource = interactionSource, onClick = onClick, indication = null) .background(ElementTheme.colors.bgCanvasDefault) @@ -195,7 +200,7 @@ private fun BoxScope.OverlayEditButton( contentAlignment = Alignment.Center, ) { Icon( - modifier = Modifier.size(editButtonSize * 20 / 30f), + modifier = Modifier.size(editIconSize), imageVector = CompoundIcons.Edit(), contentDescription = null, ) @@ -234,97 +239,45 @@ internal fun AvatarPickerViewRtlPreview() = CompositionLocalProvider( @PreviewsDayNight @Composable internal fun AvatarPickerSizesPreview() = ElementPreview { - Column { - Row { - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 24.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 32.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 64.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 96.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + // Size used across the codebase + val sizes = listOf( + AvatarSize.EditRoomDetails, + AvatarSize.EditProfileDetails, + ) + Column( + modifier = Modifier.padding(12.dp) + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + sizes.forEach { + AvatarPickerView( + state = AvatarPickerState.Pick(buttonSize = it.dp, externalPadding = PaddingValues(6.dp)), + onClick = {}, + ) + } } - Row { - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender), - type = AvatarType.User - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList), - type = AvatarType.User - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser), - type = AvatarType.User - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), - type = AvatarType.User - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser), - type = AvatarType.User - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) + Row(verticalAlignment = Alignment.CenterVertically) { + sizes.forEach { + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = it), + type = AvatarType.User, + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + } } - Row { - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender), - type = AvatarType.Space() - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList), - type = AvatarType.Space() - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser), - type = AvatarType.Space() - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), - type = AvatarType.Space() - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) - AvatarPickerView( - AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser), - type = AvatarType.Space() - ), - onClick = {}, - modifier = Modifier.padding(6.dp) - ) + Row(verticalAlignment = Alignment.CenterVertically) { + sizes.forEach { + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = it), + type = AvatarType.Space(), + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + } } } } @@ -335,8 +288,9 @@ private fun PreviewContent() { modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { + val size = AvatarSize.EditRoomDetails Text("Pick image") - AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + AvatarPickerView(AvatarPickerState.Pick(buttonSize = size.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) HorizontalDivider() Text("User avatar") @@ -345,7 +299,7 @@ private fun PreviewContent() { Text("No url") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", null, size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("@user:example.com", "User", null, size = size), type = AvatarType.User ), onClick = {}, @@ -356,7 +310,7 @@ private fun PreviewContent() { Text("Local") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("@user:example.com", "User", "content://test", size = size), type = AvatarType.User ), onClick = {}, @@ -367,7 +321,7 @@ private fun PreviewContent() { Text("MXC") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("@user:example.com", "User", "mxc://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("@user:example.com", "User", "mxc://test", size = size), type = AvatarType.User ), onClick = {}, @@ -383,7 +337,7 @@ private fun PreviewContent() { Text("No url") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Room", null, size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Room", null, size = size), type = AvatarType.Room() ), onClick = {}, @@ -394,7 +348,7 @@ private fun PreviewContent() { Text("Local") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Room", "content://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Room", "content://test", size = size), type = AvatarType.Room() ), onClick = {}, @@ -405,7 +359,7 @@ private fun PreviewContent() { Text("MXC") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Room", "mxc://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Room", "mxc://test", size = size), type = AvatarType.Room() ), onClick = {}, @@ -421,7 +375,7 @@ private fun PreviewContent() { Text("No url") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Space", null, size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Space", null, size = size), type = AvatarType.Space() ), onClick = {}, @@ -432,7 +386,7 @@ private fun PreviewContent() { Text("Local") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Space", "content://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Space", "content://test", size = size), type = AvatarType.Space() ), onClick = {}, @@ -443,7 +397,7 @@ private fun PreviewContent() { Text("MXC") AvatarPickerView( AvatarPickerState.Selected( - avatarData = AvatarData("!room:example.com", "Space", "mxc://test", size = AvatarSize.EditRoomDetails), + avatarData = AvatarData("!room:example.com", "Space", "mxc://test", size = size), type = AvatarType.Space() ), onClick = {}, From 87f33c7eb51350ddaed83f06a697ca76a45308e4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Mar 2026 15:20:03 +0100 Subject: [PATCH 064/103] Changelog for version 26.03.4 --- CHANGES.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d2a7e5428c..1b002992fb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,71 @@ +Changes in Element X v26.03.4 +============================= + + + +## What's Changed +### ✨ Features +* Add a foreground service with a wakelock for fetching push notifications by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6321 +### šŸ™Œ Improvements +* Iterate on send button colors by @bmarty in https://github.com/element-hq/element-x-android/pull/6314 +### šŸ› Bugfixes +* Fix key storage if it's broken by @andybalaam in https://github.com/element-hq/element-x-android/pull/6290 +* Improve error displayed when .well-known file is malformed by @bmarty in https://github.com/element-hq/element-x-android/pull/6370 +* Fix crash when starting a DM by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6419 +* Fix media seeking flicker by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6434 +* Fix `TransactionTooLargeExceptions` caused by Appyx by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6410 +* Fix wakelock not stopping early when notifications are disabled by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6424 +* Fix long messages not being clickable by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6356 +* Fix: "Reset identity" flow leaves backup disabled #5075 by @andybalaam in https://github.com/element-hq/element-x-android/pull/6420 +* Restore custom user certificate provider by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6451 +### šŸ—£ Translations +* Sync Strings - iterate on wording about crypto identity by @ElementBot in https://github.com/element-hq/element-x-android/pull/6352 +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6435 +### 🧱 Build +* Limit number of created PR to upgrade Posthog dependency by @bmarty in https://github.com/element-hq/element-x-android/pull/6318 +* Renovate: add a cooldown of 7 days for dependencies that we do not manage by @bmarty in https://github.com/element-hq/element-x-android/pull/6323 +* Improve Kover setup by using only convention plugins by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6213 +* Fix permissions issue. by @bmarty in https://github.com/element-hq/element-x-android/pull/6355 +* Fix permissions issue. by @bmarty in https://github.com/element-hq/element-x-android/pull/6366 +### šŸ“„ Documentation +* Add warning about new features to pull request template by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6425 +### Dependency upgrades +* fix(deps): update dependency com.posthog:posthog-android to v3.36.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6311 +* fix(deps): update dependency com.posthog:posthog-android to v3.36.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6316 +* chore(deps): update reactivecircus/android-emulator-runner action to v2.36.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6320 +* fix(deps): update dependency com.posthog:posthog-android to v3.37.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6317 +* chore(deps): update actions/download-artifact action to v8.0.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6324 +* fix(deps): update dependency com.github.matrix-org:matrix-analytics-events to v0.33.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6313 +* chore(deps): update plugin ktlint to v14.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6332 +* fix(deps): update dependency androidx.compose:compose-bom to v2026.03.00 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6329 +* fix(deps): update datastore to v1.2.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6326 +* chore(deps): update webfactory/ssh-agent action to v0.10.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6325 +* fix(deps): update activity to v1.13.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6327 +* fix(deps): update dependency io.sentry:sentry-android to v8.35.0 and enable ANR profiling by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6331 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.19 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6411 +* chore(deps): update reactivecircus/android-emulator-runner action to v2.37.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6430 +* fix(deps): update media3 to v1.9.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6445 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.23 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6444 +* fix(deps): update dependency androidx.compose.material3:material3 to v1.5.0-alpha15 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6306 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.24 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6455 +### Others +* fix(deps): update sqldelight to v2.3.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6343 +* Remove matrix.to intent filter from the AndroidManifest. by @bmarty in https://github.com/element-hq/element-x-android/pull/6345 +* Update wording of button "Enter recovery key" to "Use recovery key" by @bmarty in https://github.com/element-hq/element-x-android/pull/6357 +* Fix room member not tappable in a Thread by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6416 +* Fix keyboard not auto-opening when editing a message by @kalix127 in https://github.com/element-hq/element-x-android/pull/6412 +* Design iteration on file attachment in the timeline by @bmarty in https://github.com/element-hq/element-x-android/pull/6322 +* fix(deps): update dependency org.maplibre.gl:android-sdk to v13.0.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6428 +* Iterate on microphone icon by @bmarty in https://github.com/element-hq/element-x-android/pull/6452 +* Increase icon size of audio and files in the timeline by @bmarty in https://github.com/element-hq/element-x-android/pull/6453 +* Fix voice recording being interrupted by notifications sounds by @kalix127 in https://github.com/element-hq/element-x-android/pull/6438 + +## New Contributors +* @bxdxnn made their first contribution in https://github.com/element-hq/element-x-android/pull/6416 +* @kalix127 made their first contribution in https://github.com/element-hq/element-x-android/pull/6412 + +**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.03.3...v26.03.4 + Changes in Element X v26.03.3 ============================= From c59300d6ffc97d767485fa8266c3561c13910b1e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 15:43:04 +0100 Subject: [PATCH 065/103] Add Figma link on MatrixBadgeAtom --- .../libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt index 112de47bb2..ce0175148a 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt @@ -16,6 +16,9 @@ import io.element.android.libraries.designsystem.components.Badge import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +/** + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1960-491 + */ object MatrixBadgeAtom { data class MatrixBadgeData( val text: String, From 2e2a6e3abb31b48bd20df979c5c0d4bc19f29199 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 15:59:50 +0100 Subject: [PATCH 066/103] Import compound token v8.0.0 ./tools/compound/import_tokens.sh -b v8.0.0 --- .../compound/tokens/generated/CompoundIcons.kt | 10 ++++++++++ .../compound/tokens/generated/SemanticColors.kt | 6 +++--- .../compound/tokens/generated/SemanticColorsDark.kt | 9 ++++++--- .../tokens/generated/SemanticColorsDarkHc.kt | 9 ++++++--- .../tokens/generated/SemanticColorsLight.kt | 9 ++++++--- .../tokens/generated/SemanticColorsLightHc.kt | 9 ++++++--- .../src/main/res/drawable/ic_compound_ai.xml | 9 +++++++++ .../res/drawable/ic_compound_device_passkey.xml | 13 +++++++++++++ .../src/main/res/drawable/ic_compound_folder.xml | 9 +++++++++ 9 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_ai.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_device_passkey.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_folder.xml 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 index 456ffcf625..c5ac159b5a 100644 --- 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 @@ -148,6 +148,9 @@ object CompoundIcons { @Composable fun Delete(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_delete) } + @Composable fun DevicePasskey(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_device_passkey) + } @Composable fun Devices(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_devices) } @@ -226,6 +229,9 @@ object CompoundIcons { @Composable fun Filter(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_filter) } + @Composable fun Folder(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_folder) + } @Composable fun Forward(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_forward) } @@ -738,6 +744,7 @@ object CompoundIcons { Copy(), DarkMode(), Delete(), + DevicePasskey(), Devices(), DialPad(), Document(), @@ -764,6 +771,7 @@ object CompoundIcons { FileError(), Files(), Filter(), + Folder(), Forward(), FullScreen(), Grid(), @@ -965,6 +973,7 @@ object CompoundIcons { R.drawable.ic_compound_copy, R.drawable.ic_compound_dark_mode, R.drawable.ic_compound_delete, + R.drawable.ic_compound_device_passkey, R.drawable.ic_compound_devices, R.drawable.ic_compound_dial_pad, R.drawable.ic_compound_document, @@ -991,6 +1000,7 @@ object CompoundIcons { R.drawable.ic_compound_file_error, R.drawable.ic_compound_files, R.drawable.ic_compound_filter, + R.drawable.ic_compound_folder, R.drawable.ic_compound_forward, R.drawable.ic_compound_full_screen, R.drawable.ic_compound_grid, 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 index 4c9b20ef9f..1e3c97d179 100644 --- 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 @@ -49,12 +49,12 @@ data class SemanticColors( val bgActionTertiaryRest: Color, /** Background colour for tertiary actions. State: Selected */ val bgActionTertiarySelected: Color, - /** Badge accent background colour */ val bgBadgeAccent: Color, - /** Badge default background colour */ + val bgBadgeCritical: Color, val bgBadgeDefault: Color, - /** Badge info background colour */ val bgBadgeInfo: Color, + val bgBadgePrimary: Color, + val bgBadgeSecondary: 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. */ 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 index 9ad028f507..adeed8d5a3 100644 --- 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 @@ -37,9 +37,12 @@ val compoundColorsDark = SemanticColors( bgActionTertiaryHovered = DarkColorTokens.colorGray300, bgActionTertiaryRest = DarkColorTokens.colorThemeBg, bgActionTertiarySelected = DarkColorTokens.colorGray400, - bgBadgeAccent = DarkColorTokens.colorAlphaGreen500, - bgBadgeDefault = DarkColorTokens.colorAlphaGray500, - bgBadgeInfo = DarkColorTokens.colorAlphaBlue500, + bgBadgeAccent = DarkColorTokens.colorGreen400, + bgBadgeCritical = DarkColorTokens.colorRed300, + bgBadgeDefault = DarkColorTokens.colorThemeBg, + bgBadgeInfo = DarkColorTokens.colorBlue400, + bgBadgePrimary = DarkColorTokens.colorGray1400, + bgBadgeSecondary = DarkColorTokens.colorGray400, bgCanvasDefault = DarkColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = DarkColorTokens.colorGray300, bgCanvasDisabled = DarkColorTokens.colorGray200, 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 index 9af9edd913..9bab04f833 100644 --- 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 @@ -37,9 +37,12 @@ val compoundColorsHcDark = SemanticColors( bgActionTertiaryHovered = DarkHcColorTokens.colorGray300, bgActionTertiaryRest = DarkHcColorTokens.colorThemeBg, bgActionTertiarySelected = DarkHcColorTokens.colorGray400, - bgBadgeAccent = DarkHcColorTokens.colorAlphaGreen500, - bgBadgeDefault = DarkHcColorTokens.colorAlphaGray500, - bgBadgeInfo = DarkHcColorTokens.colorAlphaBlue500, + bgBadgeAccent = DarkHcColorTokens.colorGreen400, + bgBadgeCritical = DarkHcColorTokens.colorRed300, + bgBadgeDefault = DarkHcColorTokens.colorThemeBg, + bgBadgeInfo = DarkHcColorTokens.colorBlue400, + bgBadgePrimary = DarkHcColorTokens.colorGray1400, + bgBadgeSecondary = DarkHcColorTokens.colorGray400, bgCanvasDefault = DarkHcColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = DarkHcColorTokens.colorGray300, bgCanvasDisabled = DarkHcColorTokens.colorGray200, 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 index 6569f5a676..033efc63ef 100644 --- 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 @@ -37,9 +37,12 @@ val compoundColorsLight = SemanticColors( bgActionTertiaryHovered = LightColorTokens.colorGray300, bgActionTertiaryRest = LightColorTokens.colorThemeBg, bgActionTertiarySelected = LightColorTokens.colorGray400, - bgBadgeAccent = LightColorTokens.colorAlphaGreen400, - bgBadgeDefault = LightColorTokens.colorAlphaGray400, - bgBadgeInfo = LightColorTokens.colorAlphaBlue400, + bgBadgeAccent = LightColorTokens.colorGreen400, + bgBadgeCritical = LightColorTokens.colorRed300, + bgBadgeDefault = LightColorTokens.colorThemeBg, + bgBadgeInfo = LightColorTokens.colorBlue400, + bgBadgePrimary = LightColorTokens.colorGray1400, + bgBadgeSecondary = LightColorTokens.colorGray400, bgCanvasDefault = LightColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = LightColorTokens.colorThemeBg, bgCanvasDisabled = LightColorTokens.colorGray200, 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 index 8a8fa44e61..c1f677d156 100644 --- 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 @@ -37,9 +37,12 @@ val compoundColorsHcLight = SemanticColors( bgActionTertiaryHovered = LightHcColorTokens.colorGray300, bgActionTertiaryRest = LightHcColorTokens.colorThemeBg, bgActionTertiarySelected = LightHcColorTokens.colorGray400, - bgBadgeAccent = LightHcColorTokens.colorAlphaGreen400, - bgBadgeDefault = LightHcColorTokens.colorAlphaGray400, - bgBadgeInfo = LightHcColorTokens.colorAlphaBlue400, + bgBadgeAccent = LightHcColorTokens.colorGreen400, + bgBadgeCritical = LightHcColorTokens.colorRed300, + bgBadgeDefault = LightHcColorTokens.colorThemeBg, + bgBadgeInfo = LightHcColorTokens.colorBlue400, + bgBadgePrimary = LightHcColorTokens.colorGray1400, + bgBadgeSecondary = LightHcColorTokens.colorGray400, bgCanvasDefault = LightHcColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = LightHcColorTokens.colorThemeBg, bgCanvasDisabled = LightHcColorTokens.colorGray200, diff --git a/libraries/compound/src/main/res/drawable/ic_compound_ai.xml b/libraries/compound/src/main/res/drawable/ic_compound_ai.xml new file mode 100644 index 0000000000..2832283061 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_ai.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_device_passkey.xml b/libraries/compound/src/main/res/drawable/ic_compound_device_passkey.xml new file mode 100644 index 0000000000..a4784792a3 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_device_passkey.xml @@ -0,0 +1,13 @@ + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_folder.xml b/libraries/compound/src/main/res/drawable/ic_compound_folder.xml new file mode 100644 index 0000000000..9250d4780b --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_folder.xml @@ -0,0 +1,9 @@ + + + From dd26555c22573233b59254a47383c59a198876ba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 16:31:15 +0100 Subject: [PATCH 067/103] Update colors of permalinks. --- .../libraries/textcomposer/mentions/MentionSpan.kt | 4 ++-- .../textcomposer/mentions/MentionSpanTheme.kt | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpan.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpan.kt index 2531a605b9..b0f973b6b9 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpan.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpan.kt @@ -55,14 +55,14 @@ class MentionSpan( backgroundColor = when (type) { is MentionType.User -> if (isCurrentUser) mentionSpanTheme.currentUserBackgroundColor else mentionSpanTheme.otherBackgroundColor - is MentionType.Everyone -> mentionSpanTheme.currentUserBackgroundColor + is MentionType.Everyone -> mentionSpanTheme.otherBackgroundColor is MentionType.Room -> mentionSpanTheme.otherBackgroundColor is MentionType.Message -> mentionSpanTheme.otherBackgroundColor } textColor = when (type) { is MentionType.User -> if (isCurrentUser) mentionSpanTheme.currentUserTextColor else mentionSpanTheme.otherTextColor - is MentionType.Everyone -> mentionSpanTheme.currentUserTextColor + is MentionType.Everyone -> mentionSpanTheme.otherTextColor is MentionType.Room -> mentionSpanTheme.otherTextColor is MentionType.Message -> mentionSpanTheme.otherTextColor } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpanTheme.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpanTheme.kt index f64c8112d1..c2270e503d 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpanTheme.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/MentionSpanTheme.kt @@ -54,6 +54,7 @@ import kotlinx.collections.immutable.persistentListOf * To make this work, you need to: * 1. Call [MentionSpanTheme.updateStyles] so the colors and sizes are computed. * 2. Use either [MentionSpanTheme.updateMentionStyles] or [MentionSpan.updateTheme] to update the styles of the mention spans. + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=3236-11203 */ @Stable @SingleIn(SessionScope::class) @@ -61,10 +62,14 @@ class MentionSpanTheme(val currentUserId: UserId) { @Inject constructor(matrixClient: MatrixClient) : this(matrixClient.sessionId) - internal var currentUserTextColor: Int = 0 + internal var currentUserTextColor: Int = Color.BLACK + private set internal var currentUserBackgroundColor: Int = Color.WHITE - internal var otherTextColor: Int = 0 + private set + internal var otherTextColor: Int = Color.BLACK + private set internal var otherBackgroundColor: Int = Color.WHITE + private set private val paddingValues = PaddingValues(start = 4.dp, end = 6.dp) internal val paddingValuesPx = mutableStateOf(0 to 0) @@ -78,8 +83,8 @@ class MentionSpanTheme(val currentUserId: UserId) { fun updateStyles() { currentUserTextColor = ElementTheme.colors.textBadgeAccent.toArgb() currentUserBackgroundColor = ElementTheme.colors.bgBadgeAccent.toArgb() - otherTextColor = ElementTheme.colors.textPrimary.toArgb() - otherBackgroundColor = ElementTheme.colors.bgBadgeDefault.toArgb() + otherTextColor = ElementTheme.colors.textOnSolidPrimary.toArgb() + otherBackgroundColor = ElementTheme.colors.bgBadgePrimary.toArgb() typeface.value = ElementTheme.typography.fontBodyLgMedium.rememberTypeface().value val density = LocalDensity.current From 6689ea0e8f7900f88c04cd805266ebcd9e5c2ff2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 16:33:20 +0100 Subject: [PATCH 068/103] Add missing color in preview. --- .../element/android/compound/previews/SemanticColorsPreview.kt | 1 + 1 file changed, 1 insertion(+) 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 index c629e29866..ff7970c0f4 100644 --- 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 @@ -122,6 +122,7 @@ private fun getSemanticColors(): ImmutableMap { "bgBadgeAccent" to bgBadgeAccent, "bgBadgeDefault" to bgBadgeDefault, "bgBadgeInfo" to bgBadgeInfo, + "bgBadgePrimary" to bgBadgePrimary, "bgCanvasDefault" to bgCanvasDefault, "bgCanvasDefaultLevel1" to bgCanvasDefaultLevel1, "bgCanvasDisabled" to bgCanvasDisabled, From 7e0b95074dede957b8c0f3cb2193b12dc63dd57d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 16:39:37 +0100 Subject: [PATCH 069/103] Add border for Neutral badge. --- .../designsystem/atomic/atoms/MatrixBadgeAtom.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt index ce0175148a..f354faa69c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/MatrixBadgeAtom.kt @@ -8,8 +8,10 @@ package io.element.android.libraries.designsystem.atomic.atoms +import androidx.compose.foundation.BorderStroke import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +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.components.Badge @@ -43,6 +45,12 @@ object MatrixBadgeAtom { Type.Negative -> ElementTheme.colors.bgCriticalSubtle Type.Info -> ElementTheme.colors.bgBadgeInfo } + val borderStroke = when (data.type) { + Type.Positive -> null + Type.Neutral -> BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary) + Type.Negative -> null + Type.Info -> null + } val textColor = when (data.type) { Type.Positive -> ElementTheme.colors.textBadgeAccent Type.Neutral -> ElementTheme.colors.textPrimary @@ -61,6 +69,7 @@ object MatrixBadgeAtom { backgroundColor = backgroundColor, iconColor = iconColor, textColor = textColor, + borderStroke = borderStroke, ) } } From 36d8ea2234728673fde4d83a7e9d0f6ec713bfda Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 16:56:34 +0100 Subject: [PATCH 070/103] Edit room detail: increase avatar size. #6458 --- .../features/roomdetailsedit/impl/RoomDetailsEditView.kt | 9 ++++++--- .../designsystem/components/avatar/AvatarSize.kt | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt index 252670630f..9cdc800267 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt @@ -52,7 +52,10 @@ import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.ui.strings.CommonStrings /** - * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2204-37063 + * For space: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2216-110711 + * For room: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=3187-47342 */ @Composable fun RoomDetailsEditView( @@ -105,11 +108,11 @@ fun RoomDetailsEditView( ) { Spacer(modifier = Modifier.height(24.dp)) val avatarPickerState = remember(state.roomAvatarUrl, state.roomRawName) { - val size = AvatarSize.EditRoomDetails + val size = if (state.isSpace) AvatarSize.EditSpaceDetails else AvatarSize.EditRoomDetails val type = if (state.isSpace) AvatarType.Space() else AvatarType.Room() AvatarPickerState.Selected( avatarData = AvatarData(id = state.roomId.value, name = state.roomRawName, size = size, url = state.roomAvatarUrl), - type = type + type = type, ) } AvatarPickerView( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 8565b0575f..3d312e014f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -47,6 +47,7 @@ enum class AvatarSize(val dp: Dp) { InviteSender(16.dp), EditRoomDetails(64.dp), + EditSpaceDetails(96.dp), RoomListManageUser(96.dp), NotificationsOptIn(32.dp), From cf169dc61d21a30316911e5f6900620baa0ffcda Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Mar 2026 16:04:35 +0000 Subject: [PATCH 071/103] Update screenshots --- libraries/compound/screenshots/Compound Icons - Dark.png | 4 ++-- libraries/compound/screenshots/Compound Icons - Light.png | 4 ++-- libraries/compound/screenshots/Compound Icons - Rtl.png | 4 ++-- .../screenshots/Compound Semantic Colors - Dark HC.png | 4 ++-- .../compound/screenshots/Compound Semantic Colors - Dark.png | 4 ++-- .../screenshots/Compound Semantic Colors - Light HC.png | 4 ++-- .../compound/screenshots/Compound Semantic Colors - Light.png | 4 ++-- .../compound/screenshots/Compound Vector Icons - Dark.png | 4 ++-- .../compound/screenshots/Compound Vector Icons - Light.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsA11y_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_0_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_10_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_11_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_12_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_13_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_14_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_15_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_16_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_17_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_18_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_19_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_1_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_20_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_21_en.png | 4 ++-- .../features.roomdetails.impl_RoomDetailsDark_22_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_2_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_3_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_4_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_5_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_6_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_7_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_8_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetailsDark_9_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_0_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_10_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_11_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_12_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_13_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_14_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_15_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_16_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_17_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_18_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_19_en.png | 2 +- .../images/features.roomdetails.impl_RoomDetails_1_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_20_en.png | 2 +- .../images/features.roomdetails.impl_RoomDetails_21_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_22_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_2_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_3_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_4_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_5_en.png | 2 +- .../images/features.roomdetails.impl_RoomDetails_6_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_7_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_8_en.png | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_9_en.png | 4 ++-- ...s.userprofile.shared_UserProfileHeaderSection_Day_0_en.png | 4 ++-- ...userprofile.shared_UserProfileHeaderSection_Night_0_en.png | 4 ++-- .../features.userprofile.shared_UserProfileView_Day_2_en.png | 4 ++-- ...features.userprofile.shared_UserProfileView_Night_2_en.png | 4 ++-- ...designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png | 4 ++-- ...signsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en.png | 4 ++-- ...m.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Day_0_en.png | 4 ++-- ...atomic.atoms_MatrixBadgeAtomNeutralWrapping_Night_0_en.png | 4 ++-- ...ignsystem.atomic.atoms_MatrixBadgeAtomNeutral_Day_0_en.png | 4 ++-- ...nsystem.atomic.atoms_MatrixBadgeAtomNeutral_Night_0_en.png | 4 ++-- ...gnsystem.atomic.atoms_MatrixBadgeAtomPositive_Day_0_en.png | 4 ++-- ...system.atomic.atoms_MatrixBadgeAtomPositive_Night_0_en.png | 4 ++-- .../libraries.designsystem.components_Badge_Day_0_en.png | 4 ++-- .../libraries.designsystem.components_Badge_Night_0_en.png | 4 ++-- ...raries.designsystem.theme.components_AllIcons_Icons_en.png | 4 ++-- ...tcomposer.mentions_MentionSpanThemeInTimeline_Day_0_en.png | 4 ++-- ...omposer.mentions_MentionSpanThemeInTimeline_Night_0_en.png | 4 ++-- ...raries.textcomposer.mentions_MentionSpanTheme_Day_0_en.png | 4 ++-- ...ries.textcomposer.mentions_MentionSpanTheme_Night_0_en.png | 4 ++-- 75 files changed, 147 insertions(+), 147 deletions(-) diff --git a/libraries/compound/screenshots/Compound Icons - Dark.png b/libraries/compound/screenshots/Compound Icons - Dark.png index a381536ce4..f140517dff 100644 --- a/libraries/compound/screenshots/Compound Icons - Dark.png +++ b/libraries/compound/screenshots/Compound Icons - Dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:460ddd253f4029b29edde9d858237204acb55aca7e13e92bc691ea71ca34c53e -size 237462 +oid sha256:37f6acca46890e98087ece62e2716fa60791479fab02999406050517e3b79307 +size 240187 diff --git a/libraries/compound/screenshots/Compound Icons - Light.png b/libraries/compound/screenshots/Compound Icons - Light.png index c26dbc59cb..c84421b6fa 100644 --- a/libraries/compound/screenshots/Compound Icons - Light.png +++ b/libraries/compound/screenshots/Compound Icons - Light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0b76eee73be6a2ba58eb12883477ebce7daf039b6c60637e263a478a0bc68fe -size 250668 +oid sha256:a2de5e6d24dcbe0baa75a69485f5a308466fa599625bcbdb0cb96e9bc5a1b708 +size 253233 diff --git a/libraries/compound/screenshots/Compound Icons - Rtl.png b/libraries/compound/screenshots/Compound Icons - Rtl.png index 0af5bf0631..89be63840a 100644 --- a/libraries/compound/screenshots/Compound Icons - Rtl.png +++ b/libraries/compound/screenshots/Compound Icons - Rtl.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d12abdfa2a2d7d1943e0e377279134b44de0ad5d8fb12b09e23c2083b728989f -size 251951 +oid sha256:ae1cb46d82acbb23cc172f41e20a41bbe88c350ab53c20e5b2a91f2c16590fbf +size 254525 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png index 2a9029e303..c70e44cacd 100644 --- a/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png +++ b/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:afb0295b04f302c25f40774562e7d5b2bb668c4cf1158b521ae9b50a35a58d2b -size 322068 +oid sha256:a9334d37f010d4e520b11dbd16d664fbb4413497d371dc8b0af0157faf870451 +size 323086 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark.png index 60761e34e0..45be3e910d 100644 --- a/libraries/compound/screenshots/Compound Semantic Colors - Dark.png +++ b/libraries/compound/screenshots/Compound Semantic Colors - Dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b94a6d004999869b8650559a70a1427882408b242c9b47788e56320aaeef34c -size 320114 +oid sha256:9e016ef5e07de6f6e86e5e6104d78502f5ee15ecb39d1533f020cf94ac087603 +size 320821 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png index d20e3628c7..bfcd41eb92 100644 --- a/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png +++ b/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06cebaaf9e0e4f2b69231ab2b866652419e70df50b0abb68288e08f748ed9b76 -size 301985 +oid sha256:93df69ddd7a1571abcb868495edb9914b5d832c1e55f1520a1c04a71de59577f +size 302213 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light.png b/libraries/compound/screenshots/Compound Semantic Colors - Light.png index 213f90fbc7..4d5e171d7d 100644 --- a/libraries/compound/screenshots/Compound Semantic Colors - Light.png +++ b/libraries/compound/screenshots/Compound Semantic Colors - Light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:baf841165dfd7c6315dc7bd82d1be8935976d0a9a70e83f4d70e23a2389dab95 -size 301760 +oid sha256:b1eb3a0283e42d2e2d1083c95fd2bbd2e338fcc5f318c07386f04cfb97e6fed7 +size 301963 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Dark.png b/libraries/compound/screenshots/Compound Vector Icons - Dark.png index b50dc7b82a..702fd9b425 100644 --- a/libraries/compound/screenshots/Compound Vector Icons - Dark.png +++ b/libraries/compound/screenshots/Compound Vector Icons - Dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40f0940bd8a5ddee96ea2aac01d9672478fc15044621bfb10f5f0b20d61f035d -size 93402 +oid sha256:8a8a9b6e61758a40d01028a4edb4a4d21b845b83b3e0793ed0934e48f3d9eea0 +size 94637 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Light.png b/libraries/compound/screenshots/Compound Vector Icons - Light.png index 5e32ca9c59..76b1cc49bd 100644 --- a/libraries/compound/screenshots/Compound Vector Icons - Light.png +++ b/libraries/compound/screenshots/Compound Vector Icons - Light.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48d8c1bef4a59554649fab33aa716ca2e9fe24f29a6b7e0dae9c404afedd6695 -size 99735 +oid sha256:7f29d225df71587fefe07ec8739b84f1a0469786c6b1d6778da0bad33d19574e +size 101183 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png index 42f695d569..3df4b3886c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f74b2d87e7dd5e431c6d6add3131472d31c9ffcce900736ed489af2c667783c -size 78968 +oid sha256:dbbd62622843fbd1d8d35b63c7308eaed46b488e6b189e987983144e5395bd09 +size 78972 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_0_en.png index 45c428bf80..44e3d87eb9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5ec03b736a2b1c641747a49be5417a3e9b6e034c865294bfd71a5bed8f53834 -size 42930 +oid sha256:31d18a5e250e531fd7b986690306366cf69eedcfdbaba28148e3edd1d36ae597 +size 42912 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_10_en.png index 4cf62739e4..449dbd7465 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ecdd3041a962680b76ccfbc02872f4caef0df30d239cbc00c7c9759d573ee03 -size 41615 +oid sha256:a04a5aa9e35df5eb82a0a708b2b743bb83a1a9408fee91beff60d5a1ce2c6d5d +size 41599 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_11_en.png index 1408646027..279035fea1 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bbf72a26a32f180d1dddc276adda01fb8586e6c182b32dde35d7daca55bc6ae -size 40765 +oid sha256:ef69f889a28afe5704da86296ebf9916a7af1de751eb4c1ee4995ca3f70ea12d +size 40737 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_12_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_12_en.png index ff177b8e06..72f8640e83 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fb05bc1ca83f872c88b36097fca767c36fa0688c19bd504674846707eedc358 -size 42192 +oid sha256:1d4312936ba67965a8b35e714bbc3014214320311c5d077d33382ebb5aca5738 +size 42172 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_13_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_13_en.png index e7fcdbf5a2..7c1059539b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7fe45d21c630e31b44ae7a8cb17b9f89b0b0f67d00b3769035516f0e827f64a2 -size 42098 +oid sha256:4b07f6c942ab083d94c22218010b4aa646cf03e87af41fbda89b16620f7b9752 +size 42079 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_14_en.png index cf005e1dfc..d7691fa7e2 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de164fd028b96c6c53ae2e33246bfb5bda1e6beba1c91cbd00111d2fbba92cd8 -size 42658 +oid sha256:1b6db26bd05f206661a5707a972cb6f843eef82c76e5e0035775625b4a6268a4 +size 42640 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_15_en.png index 3696ac101a..9e68ee9859 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd7a8279d58ba0420c884cdcbf1972772d2d577024c3b766cd535c5cabfe8cba -size 43196 +oid sha256:5f77eba1f623f67eba427312523def9a45c41581dd4e047701b2c75f787fcffc +size 43178 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_16_en.png index 89ce64548b..c42d3ebe59 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59d38b1cde9e22b1c47b2c7932ba980b2c56af2fa8b6b25200cb46ee3a0cd145 -size 42440 +oid sha256:a62965a57fea6665739d8e8b2fda9e15abf119ea59f6bbd5d7d8a269512064b9 +size 42421 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_17_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_17_en.png index 0a8eb52edb..45da7b512e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de0c605c7845f2e590aba1d0484700bdecb80effc16899b6288301cd91a9d966 -size 41703 +oid sha256:39780082d7826422d70902ac2b7859013c30b41d31f20aefc25ada8aeae196c2 +size 41684 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_18_en.png index e35c1c48d5..029a2c3639 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88a2e1d2000e3034fa2d9e37b3b69aa47a7f588fee40efb8a8c74f9292315ea1 -size 39678 +oid sha256:5917028dda35add5ed6b32fa9017a9cdcdfb8d273d230aa6d529bebfbf0b95c8 +size 39646 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_19_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_19_en.png index 6f325f6503..55a953b2df 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59c7e92e09d585e18f552db5e9fa55dfe79cb6af028493cafc11f0ffee8344bd -size 39634 +oid sha256:f65f298b3f14ecb0da53f03a20a5464a7f6ae138dfdf417ad936601a521fbb30 +size 39601 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_1_en.png index 26dfe2ec3f..7f4cd39731 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:405b81267a5a14771a69c8b06efea888b2fdc588bec26872b9564a66bb5496cf -size 38110 +oid sha256:df3ceef42a59cc072e3aa21c89e9b90f0524ac422d1538804b6fcb8abf97752e +size 38090 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_20_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_20_en.png index 573476b244..7cc47cba6d 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_20_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_20_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7b0f5cbfc01a4539757611a9800d18ed19cb732e44eee4f1bed41788d4b0918 -size 45142 +oid sha256:c66ebe3c16933495fe33596036363f95e20654b6ef5ee822f594a34531ea640f +size 45211 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_21_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_21_en.png index f3df601803..8d4880b59f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_21_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_21_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:acd1c2c73c21370b816792de80d0183bacadb213cf0bf005c73695df553fad3a -size 44979 +oid sha256:de5ccdad3e08ed4fd4330697ad6c7085d5553cb889b7b7c12879aaaa6b34c1de +size 44953 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_22_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_22_en.png index 1d12fe7bb6..52e66c38c8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_22_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_22_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ad520c5dc49852a8934bc85fcbcd982e500e8d9818635605abacfc51f29dfde -size 44621 +oid sha256:e215296d864d34ceacaa53e7fec452643b63d72b253074eb50617bab50915ad1 +size 44670 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_2_en.png index c95ef29bb7..23ccf2249a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bf88dda52209b3ff194c70a4c783a8e3765c352d58eb00cb0dd9aa16d3c6578 -size 36614 +oid sha256:0bf5c596196e64554117addd1247aa1e5be6e8095d85a595b1c2a6232ed483eb +size 36591 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_3_en.png index 31c90c349b..8a7f2e2d75 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09c7b2efe4a3dba7028810fb10dbc7a3c3be4e1fc012319bd868bb3d392487ae -size 42344 +oid sha256:b0cc874a4ba2b8bd0f0b7e290d0ffc67e82d1222fd287360c3321143d5f87ad4 +size 42369 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_4_en.png index 9685ef8b53..36de539c48 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5132f788bbfb0fe37254ebf53823f04ab0c303cc65770a3a089f8e7a3e2277e5 -size 41374 +oid sha256:6900db132e6b79de1c5ac986666af46e3f7ef65a9c4cc7d847dde6962eadd129 +size 41352 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_5_en.png index 3f8fafe409..c5d81c75e3 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f36006f661e4dfb2c8669983194f5b22cf54292bc975939c9a8c2832b47b799 -size 39320 +oid sha256:b7199817c8591ccf11241204af8a39d2ed1a60dfe238b06387749d57858cfa65 +size 39288 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_6_en.png index 8f9a9d52ae..1e0b3070ee 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:51100671549be5aee9e67f2e43f22015b75edb3d39fa1f900481416d1d65e8b3 -size 42689 +oid sha256:0fac98b00a99771b186e8146b98ab63602be7b4c5cc9febc3ca821c1d5cd6a1b +size 42700 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_7_en.png index 0d7b0cc086..4b9b30b2ba 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07ec8a7ab75acad9b31b6e6352f0e79cfc473fe7756c55c3101977b680136ce9 -size 43113 +oid sha256:ed4073d3b427b2a314667f5118b571e5896f1439582b9209077ec9c62ee0e061 +size 43097 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_8_en.png index b313a4d8c2..60200cea9a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc85e38b6ec98b12c4fe40b0338dc80033120d5224007b1e8f641165d313ca0b -size 42119 +oid sha256:c68c895b189a41c7edf8fee58202560ef47e0a98082ddc3a346546f4f1346de7 +size 42100 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_9_en.png index ad1ad1f828..f9287533ca 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c13a57f8e460a7f6b06b1d81c10b3a2bc8dfbcda9bd2bd7c7d5224374a1b192 -size 42108 +oid sha256:e1879c3d54dfed55e4bb46d967c9c8c5a4f95f4e31e884afde4c9c517f35402e +size 42093 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_0_en.png index 15958517a5..bb868da01c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdbbba4d6ebf3eac1d096fe13e5685aa10ab90972af322975fa2b3687737afb9 -size 43656 +oid sha256:e2b5dc5cd20ccfdb7e6a1accabf6e139ff343c16378af19232168f835b1c97df +size 43650 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_10_en.png index 1962391329..72803025b8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5ffc7f9970dcbb0510b37db1e2eeca3b41ebe9ff3437014d9ffef6935bd6733 -size 42330 +oid sha256:f9c7dce94908b2b0287c196f564c306a05306f058c71d75be3b298a45683bce4 +size 42321 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_11_en.png index bccf06c807..9d2b424654 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:446a52c50158d9855269dbe62746d6a5fea94a6850d16fb29763b6b3bda67cd9 -size 41472 +oid sha256:743fcac827e8df7742127491722c3ce617a54c0b64fd3336f939994b45376966 +size 41470 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_12_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_12_en.png index 0729f52acb..dd489b5147 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e518928f4a23a4e72cd09e300d332ce75a700ca4baf573fe48af509fe73418a -size 42929 +oid sha256:671ae1ee2f065705b38063cb354c4bb4a63247e01e1101dd155515b46decb660 +size 42926 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_13_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_13_en.png index db83e1f900..d5f14e286e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e5cdb25bd944c13580ff2f8b5142e2c2793965bb233c7f663cdf45bde96bf26 -size 42855 +oid sha256:8f352ad92472cb8b152ef0660c7f66b55b956ec05bd11dbeb2c9aa543d0db2ca +size 42849 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_14_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_14_en.png index 31ec0d63a0..cc8b1c74e1 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a364c3b8edd68c4e4c944844db649cb22ac5db8931836a7f91d4d0f65329e4a5 -size 43374 +oid sha256:5742ffdefde6a9e3f01ba021a75eea20599cc520fa4976aa45cf1c10e394f62b +size 43367 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_15_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_15_en.png index 5412e027aa..c9db5d9a07 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ab0a2daf8d2fc3b918b2fb3c9a860979476e0fa534a074089559d77952f9997 -size 43973 +oid sha256:0f6be8e586f9692013ce38c483c42fb23f8c135593e17a72f3be19381719fe6c +size 43967 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_16_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_16_en.png index 51024557dc..6b9fc92803 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d0c501c1b3f14d71af64d98c6487cbea150ca6b8e72f0f4675b16aa4fcaba4e -size 43199 +oid sha256:7b4b470aa3f3650c26c6e1cf2491ffb7c3ea58db28dd00c0755a7f5727dc60f1 +size 43192 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_17_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_17_en.png index 89840a00a9..12b5fd1b6d 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef7b68c5f009bb02529313f0330e0c3563e1840395ac4d306cb52e1ce34bbc57 -size 42689 +oid sha256:656c300cea79355aa3b35cd59666f8e35aa4c09d69dd422e816f256cbe6d420d +size 42685 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_18_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_18_en.png index 0bc9a6df9d..4c7d16ea22 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44fc7317e29697583ba1beace7a4cb0dd366e25d1e54878be5ebeb76eea9db3d -size 40374 +oid sha256:93fe116bc34f9cf8ee3da2317948a98405e36a6fb98a58b2046a049af435e913 +size 40373 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_19_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_19_en.png index ab59d161e8..33efb5e55e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77ad55f57eac496eec3d8f9dbbb448ed75d3bf0e9ecb0818c0fe2517c6936605 +oid sha256:09f89c67652965407ea147aef158d0b3281850b95cca35f7aec207693bb0af62 size 40242 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_1_en.png index 6ea6d355c2..5e8f3baa0e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:959c978957721a609fa30439b3fa6dabda4fad6bf270fe40b383b380f75e08f5 -size 38962 +oid sha256:04c7f8e85d58591c3dd6ade913b9fe0861ff7f774fdb4b46e63c9f86ef5a918a +size 38959 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_20_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_20_en.png index 4c60c59031..9462f1336b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_20_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_20_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4608b96994eef19bd9f712324d1d0c53922dc9856aa4da8c6e2a645e6abc2d84 +oid sha256:389fcb65c5334f31b3d66731de2c65128d0a17e7380ca7c45be8a36023719732 size 46097 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_21_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_21_en.png index bf6142d66d..f1f9639eae 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_21_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_21_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37bfa4e42fdca66940aca53335958935d37f027ae38088d04117936caae83740 -size 45841 +oid sha256:567cefb525795b66704ccd1738bfe08247004814c947f6c60801588304c768c2 +size 45835 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_22_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_22_en.png index 5bd41696fb..fb830369a5 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_22_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_22_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b536ee9e04ee12f64ce37ffb27bb1e60100fd9f817e07ddc50e396eb567519e1 -size 45513 +oid sha256:f87512e18ca91237141d97ed03f4725a8a671268daf50f0a8049ee34bdc42a61 +size 45503 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_2_en.png index 123d33df18..cb6e8c1f80 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0da00de6d2570c210920bfbeb0caec61390f795aa9f6ab08afdfc6ecb228fe8 -size 37385 +oid sha256:27918a9baa05b2cb8dee7219b6e19cc10be1421be190d1e35724d237270761af +size 37382 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_3_en.png index b07c5d98ae..a64f6a2843 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9eeb48387ff960b03efbd78eb360a75db4e997550a56613d9c577032c7254086 -size 43071 +oid sha256:cfd96490ce4509620efd7be72e6ecca219eafe73050417c0c3685339444457f1 +size 43060 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_4_en.png index ab58c7930f..a8894c7eab 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea8aabb87ff7bd6c97e892183d1d680043024c2966ea2c846147f99198238e3b -size 42076 +oid sha256:8ee0a79abd45fc9573e64b6f06491f33dfca34ddd96c0dbd3d8cf7a9052b47be +size 42072 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_5_en.png index 44753c8d7c..cc81464baa 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59a2ea7ae299bdc50c5fae263792034083837d6b693b7006e8f67b0d6ba53238 +oid sha256:e7146d365a105c86eecc34027d2b824e90ca1615fcf77ca0f49ed920dbffe22d size 39903 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_6_en.png index d6afca2835..2f72417b73 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6dc12c6ede2e635bf99eca3d1d5994b7b15cceade074835d8751184203f902a -size 43437 +oid sha256:dd455b5b492eb88bde4e985ca01ab97e23a337d7ac478782c09dbb10803960f2 +size 43430 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_7_en.png index 9680df6edf..55d8ab9869 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:237628b9401f68f6470fd27b31368959735209343226a7fc527042e02944bfce -size 44062 +oid sha256:863c5db2d8fd863b057d0ddfe26bb3804d15126c2fdb58fc03c0087d79c6a3b3 +size 44056 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_8_en.png index 9b76e484c5..83b9c7131d 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b86881ab66a8dc3168c12b26f376f7e1f8f906106c695f79d40c83450abdfb87 -size 42974 +oid sha256:16b815f5ec48c101a7bde78cd5a4e30e825138f359e415699ef2b14e6ea23869 +size 42968 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_9_en.png index 35a76b346e..faf5081313 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f37c7d7f53a3b45f5b1ba899b0aae0ad4d0fcf05e02ad5e3f22d0dc48ff99d8 -size 42920 +oid sha256:5c47ff32beec1987fdb9f92ef6e5c9b7eca04ab20ebab576a2028225a595ba12 +size 42911 diff --git a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Day_0_en.png index ac2b7d8251..cf5c451505 100644 --- a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d0fb9b5f71d7fa707e729c6f2bf03ac84a41083aff5e7e01167e1eea7d3562e -size 15816 +oid sha256:d09796f261ba9552fd94f595467a958ff7cf7113c3ca23117128cdf76f729e43 +size 15808 diff --git a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Night_0_en.png index 2f9e1f6f73..09475dd0ac 100644 --- a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileHeaderSection_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f54708f3b2dfc736b56fc16171d1cfe02edd0249c0f512a475ee3b12d1f591b6 -size 15288 +oid sha256:49216216b3078897afd41a04c3eea2d82cc89d13390c2f61ef8045b84ad69e6f +size 15253 diff --git a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Day_2_en.png index 42bb3943bc..7951440a2f 100644 --- a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4748c82e6b7cdcb253b8ae66f3a864b853b917ee3c3e383ed2593f4a658ccb39 -size 24119 +oid sha256:c8185065602221f9bf675398d42c16f9e0c7ae65952b865689263878f43c545d +size 24110 diff --git a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Night_2_en.png index 6a754fe9bb..61d82d6084 100644 --- a/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.userprofile.shared_UserProfileView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c6416369951a98fcf0d9d47ab2334a5d4ddb4158e98ed4c7fe813c972086d17 -size 23406 +oid sha256:c2f2787f0aacfa36596b9fa0e25d990710870bf5ed25d831b47c5c71ac1d3de9 +size 23377 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png index feab991498..2585456691 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c5ab08fd350c52731c452ced5fc84126c4a07b6c8c928771d07ccbe93b8bfa1 -size 7021 +oid sha256:1d32b426d7cae8b546e46d32f7f72df4f69e2970314fc2ec15862d8ce3d12eb9 +size 7020 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en.png index f1b3d363a2..06a32671f1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1179ae118e0d6dccf9bd8e8efb348097c57000a272e6db10aef89d63e39793b4 -size 7055 +oid sha256:c2ed4a18e8948ec3833672ac652e2ca70fec3cbe924d076abe0105e0d66cc25f +size 7075 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Day_0_en.png index 91d0230dfa..f959bb4946 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c2927630d92470fb5b31ef2ae784503cdfe664454ee704840e9f900fe0b8336 -size 11221 +oid sha256:3b0a6ea09a6f9c379091b302ca6bfc6908d00e5dbe8fbe066fd928ec71f384d5 +size 11209 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Night_0_en.png index e582a39a0b..378e07b205 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutralWrapping_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd7ec0765858685bba7204c8ce8eed7ab2ccfa6da63bee40969d9aef73bb7b66 -size 10929 +oid sha256:f8c39bf49a723f85c5498a7053d3a217799714f516bb7b29f02faccaa83a4fef +size 11101 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Day_0_en.png index 7fd4d93783..0f6477407e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c80bde437facc798f16a0cc3bab3bcfb87f397d3c93435187dc884153d3c8687 -size 6599 +oid sha256:eeb2ba9d688bfde4d132160a4ec0831f60553e711e1c4785a44021e09c0efefd +size 7201 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Night_0_en.png index c7f2f0d932..cfa8f459ac 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomNeutral_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bc002ccf56305a29616d558c649ee7d968d266e14370356d37e979f215c5b27 -size 6519 +oid sha256:3dafd293025165b04ae5251dfa51f70194a7bed29a0733addae0c020c45111a7 +size 6891 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Day_0_en.png index 7e247bf028..79ecae8c74 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e358069d7ed1dd400229b43a1a03f28b207ded4aa136b3c10d14e3b5a5219a7 -size 6121 +oid sha256:3f8e5a17d0e708d07a2f647182d6dc60c0743525e742ad5b29ea85dde2b3c98a +size 6152 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Night_0_en.png index 4347526f27..2a9b98da70 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_MatrixBadgeAtomPositive_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f8b8b5f9bacec61f7c26900892ed66fb617dbf48ca480c89bd018eae26f39e0 -size 5948 +oid sha256:50e26cbaf181985f54841b7980b52608cc2538fdbbebecc59db11c46adf0a9a7 +size 5890 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Day_0_en.png index bac09c24d0..a81d1ea293 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ef9bf04799938362a779395e15604a6ab43b56a6ec01852d1809b13efca6e92 -size 6058 +oid sha256:0948159715db7a499836e0bf2ed90b606d8665a20ce62c893532d38027aaafbf +size 6078 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Night_0_en.png index 938132c91f..4fbef95ce7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_Badge_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee4e7eae43d9c614024dc1748fe57d63846e64a8e1580dae0a54622259dbe6d3 -size 5927 +oid sha256:cb978b7caec38e27178eaed3be60a15ca775c56bf184a3d3af045e5f3e769913 +size 5848 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_AllIcons_Icons_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_AllIcons_Icons_en.png index d137fa3678..e3cda24208 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_AllIcons_Icons_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_AllIcons_Icons_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9af7cbe72cb2e9905ed8b4eb7f9007eaf92bc8dec5b23e0af46d7b41f770b2a8 -size 113751 +oid sha256:ca6ffe10dd122a2c2df99160b4e318e591ef6d3b10b6173d36f6c9959a93277f +size 114895 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Day_0_en.png index 1c9fbf106e..627828a287 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae9e5cfc2a2e42d826ac473caa4e75d9809f67ac042dddba5a1179e8afa30148 -size 35483 +oid sha256:8e171ced0a7f9994d1e9addb093959fb455727d81912aecb377742541181535a +size 35733 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Night_0_en.png index e8290da3f8..ee87ced6f5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanThemeInTimeline_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db850df46ede0e167b4fc899a26251686cbf0e4e076adecc7664983bd6219168 -size 33680 +oid sha256:ba17ec26a4807e2cad64769b98140e2d77f133e39be72090a1f44ca143427833 +size 34106 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en.png index cf326193b2..140398dcaa 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4422ff263313e4c635917621c989c827cb2f6fa1068d1d202bcc459a016c7970 -size 51379 +oid sha256:8366d3c9ea45d6b7e24184b5ba9756cfcfe8a592ec19b107be1168b307840192 +size 49433 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en.png index cbb0791e24..0c0a38fbd5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a252d6bc04efa61952f32336f7f1bcd0eac99938a74ef33782cc555c6f7fc5c -size 48721 +oid sha256:79cc95b3838f24e85a87d5f0116575ad74e2abc03b77a28464d7fa82fb357840 +size 47343 From 42b00debdceb72728fc540aa3df609c7a298d800 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Mar 2026 16:16:30 +0000 Subject: [PATCH 072/103] Update screenshots --- ...ces.impl.user.editprofile_EditUserProfileView_Day_0_en.png | 4 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_1_en.png | 4 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_2_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_0_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_1_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_2_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png | 4 ++-- ...raries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png | 4 ++-- ...ries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png | 4 ++-- ...ries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png | 4 ++-- ...es.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png | 4 ++-- ...braries.matrix.ui.components_AvatarPickerView_Day_0_en.png | 4 ++-- ...aries.matrix.ui.components_AvatarPickerView_Night_0_en.png | 4 ++-- 30 files changed, 60 insertions(+), 60 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png index e3a8861914..9799fbaa3b 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d5a1632a25fc84bc9c6df9c1c06e9120445428003ddb753565c7887d3e71a74 -size 21847 +oid sha256:586a7b5e6beec2d88b0d10582629286c13581ed5387b84d6b249c40fffaa2d34 +size 20770 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png index e680a887e5..4768b5d340 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ace8ec66513954fec104f6e2eb1745353b1e6eb417b27137416de057032fc33 -size 61896 +oid sha256:c722a89bae7665b070dd56de6d0c126fec2f5a94dc00898ff2376f5a83707d72 +size 67672 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png index 4870b36647..cd95db86ad 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d410125b5f6a0dd5865f0a0d05f5a88a8fa6651cffde717637cf671ac348067 -size 30405 +oid sha256:a869fac21796ec8df3690ab4247de9d93fc56e799d2651565ffbf9c1890f5871 +size 29533 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png index 1fdbdbae4a..370ff83322 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:326bbf9055be0fcf5199e3841e71cab10c16bbf9d1762ba30f054ecfcc453ec7 -size 22007 +oid sha256:0d5b8083d08321c3e28c4ffabd69a92e8814bd3c9f4280ca053b82c512a726ca +size 20943 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png index d7a12e749e..b514034d21 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a49d67f69827a414243a5d2ee82dc7202fd6b324ba66c43822f82a2249120a3d -size 60631 +oid sha256:ef92f484c434661efe6d4bc12a9e9d1cc34f22af5be7f21c2ef7ff21d1d297dd +size 66367 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png index c6be9a691a..67988f34f0 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a44fb8fb3906a05277b1702aa81ce6b5674539624067019626a6c2daebf7edb2 -size 29638 +oid sha256:8673ca44146ce3857044c97bfb1433589049b94700a9a8dc67c67010aefd0332 +size 28757 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png index 89c8f402b5..994ee48148 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c2a3c20783c325f8713968cd3c4d801d9cee9b29b5d785e5b740bbf3801e72e -size 27871 +oid sha256:951b83b0bfd170a3ba4971dc6949dbccde3036566a7195a7bd54fbf39651fae8 +size 27882 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png index b0c5e5058e..ba6e503037 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3a4401f3b9ae9a13e455c66503b5acc7673f1489f2bed147832fbcb8258f370 -size 21717 +oid sha256:1803b6697e92d06a14cf45cd6f00c75048bd04b137e9a9e33c27baed3df2a4f9 +size 21726 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png index e688484979..48061ca798 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aef2d95eaa65345bb0957a30ae86f5794d5d6a6e09d8108eadd1d78d67d9fde9 -size 29262 +oid sha256:34e0bfac23207fec8ef658bbc5bfd5d409b2e10153a96890143ecb8ba5a65107 +size 29261 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png index dc6ab73909..c9a791d3fa 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:019539b32a13702d3983ca5b7bb682b2dfe9d578e5eb8dbcb5be9243faa08627 -size 47531 +oid sha256:d696e56868273dda3c28b73db40b23ffcf040190a39345b79e8f2379fcf079f8 +size 47576 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png index 11e42a8678..a49586692a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cfbd1da60262d20c2ea316105879b2fb561d9821fbea402e131c1f029513fc8 -size 44791 +oid sha256:045964005f4c6a30f47a757d7667e417265037575614d880bf403538868698b0 +size 75800 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png index b148f83300..167a4d0ee3 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c02ee5dbd57bcd4605e4e8fb650684b4766b68364d8252dda2783f7a663eccd -size 27934 +oid sha256:bfb25905d1408481cff158a95fe92d30cf5fb5f41e881189846aa4ac4aa6e7c0 +size 27945 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png index 771ade2cfb..d2376de763 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa981dcbdc98e7e8b7d15be7055c2285326ac27c8c49f5487bcddb00f79d687a -size 24933 +oid sha256:1bd48eb9751d287a8f0177fa143c4933188d401ce0edbcc10c964b094c8347b4 +size 24949 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png index e2c1180058..d86071767c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c134a2a60c7ad1b5d84dade390ad435fdc25290f97daad8da442ee47867afd6d -size 26025 +oid sha256:60f30e9fb44614969c54cb3413fe7a3cc808a761ef6ad3699754cf6dd86ff438 +size 26041 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png index 421037c3d0..a935aa4163 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d04782b64e26a5013cfc5f5f1be217a51d919a1833f365b67f60f57ef926419c -size 29101 +oid sha256:cd5ea2bec707ca4af076b00e5baa6491a6bcc9336bb710ffaadb5a2f7f92bbb0 +size 29117 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png index 1925a66cd9..584ae67023 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74648fccd925a279ce090251b931bc5845e305fd0e1262f6e424b7d58b2fd342 -size 27290 +oid sha256:fbc3e7d76dbd4e3b4a6f8301252ce2bdaecdf81eeeb14e5b65cbddd55efef782 +size 27285 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png index 24f05a2689..377f077aae 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82e8e8d0cc0dbde32d0de399b5a9e3ae4d2e0e6366ba70416aa852ac348464e3 -size 21359 +oid sha256:96f77d742b750a9231ed9869d2f9e777aee820119756ad14b178344d65d88fe3 +size 21356 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png index e77e4b00c2..09a64cae1a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f235b2be28c26a4d12fc67fa0fb791add8710f34d4efcd452dce7c3c7ffe50da -size 28765 +oid sha256:b534bfcb56d1115bd0ade1855c90fba54a1b855e416bf8fa27181e6afb72ac0d +size 28763 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png index 7f61a28ce8..edff67469b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b76fbebf6bb05c4dd365e9bb4da5fbc97b00029333d378bef0cc0bcc9a38cbfd -size 46251 +oid sha256:069a87a2ed3d0db5c8d7c11d964a59a6547b109c9bcc0bb0c7acb23e14e4ba06 +size 46287 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png index ee7f0b57b8..27d020acec 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6dfe47955218be4322b6a4ef18631d6b286e0dee38ed7017706fa30e82d9c83 -size 43633 +oid sha256:71c0dbacffcaa89facd5eb285ebde2f9e87bcad38893d0f41fca99c8e567878c +size 74526 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png index 15db2ba218..1130e90791 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01149ef85301bd448d9fedaa4d2d7dda6f9ed5392d1af1763dc9aae16c87c000 -size 27261 +oid sha256:d2ce39e48f12e57a8a0d57c6c7f6de829ba8e4bb839ed837c081651587c9b2ee +size 27262 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png index 95b23bf68b..cd4b5431e6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e37b19634d2e801d4e31fb826e87286dfe1333762e043fbb6c96910234dfdc11 -size 24303 +oid sha256:197b5d107cb9fe04f527e42907c8e59238a6f30d72a70854939ee24625df8a16 +size 24281 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png index ff3c793fca..7e4f228076 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:368fb87d29e66245a70bf83cd7a0b422c6bf760e6634dac00ab633d1316ff4fb -size 24582 +oid sha256:d1775ee8969ebc8755686b142f9e13fca28936d2f18b01d8c6cac1e3704313cb +size 24561 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png index 84e45f955c..1f7c54dac2 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a751079af9e755ba5858176c81e49178c7141bd977f627dd21e1e8e4fef3caa9 -size 27632 +oid sha256:8178051267f0eda8dae95ae44aaf05ec40902e7d1b2e93ca8259beedc408fde5 +size 27608 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png index e080edf472..f4a4b0a258 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b39e11e7b301b4aace05efbc4cbcf5c9273e0a946b9982fcaeeb2aeebedc1146 -size 207976 +oid sha256:f35a413408b92d441fa785469de5560db87ba0efb94db94afa7d46a3751c5bef +size 165369 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png index e8584bb160..87c9bc22bf 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55bfc5e3f65bc8e31b32bffb133f101d624c873ae0976c5108a1b5c8543d14af -size 203310 +oid sha256:e9ecd308fd5ce7b9fd25204d696fcdad835e41ff41b00d2b8635981b290da02a +size 162184 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png index d1abfc3a7d..c4375fefcb 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68d55addf93d6aa72f5f3752ff41016bd106b2ce552f06c0f2e4d21cd536313c -size 171905 +oid sha256:806e56c218a0ad1c69dd997089cc8362e30624377fdceffeefadc523c712203b +size 173137 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png index dbae2173ee..f946b46642 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa60d59d4beb4a11795897e112be156ce58d4347d039a1a163df519819c880ab -size 168619 +oid sha256:e25f6630680dcdf1e685235fc551dd6ea853b0902f30234e5fb9d4050f584450 +size 169862 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png index 68c57c8de1..7cea979d00 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60e9a853870a1f8e405619f3ed156f1eb122e08a5d2c102d5c16566e6911398a -size 170340 +oid sha256:8185dee1ad113c2b32a74de58c440abb366337accd1dea12047a85d323eff9eb +size 171610 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png index 442d12e9bb..7118f2310c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b219ab086da6c8b7b72f19da8a7c728ee6ebeaacde7ef749a1586289b2ac6e9 -size 166821 +oid sha256:a13dd8a9228c1526482f0c7fd5e0347c8fa4998849507b759a0c9548455adfe7 +size 167957 From da8e18eeab202f4d608e694c555511417e131331 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Mar 2026 18:06:08 +0100 Subject: [PATCH 073/103] Use Folder icon from Compound. --- .../android/features/viewfolder/impl/folder/ViewFolderView.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/folder/ViewFolderView.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/folder/ViewFolderView.kt index 2a6b4031ef..dce5ffeae3 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/folder/ViewFolderView.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/folder/ViewFolderView.kt @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Folder import androidx.compose.material.icons.outlined.SubdirectoryArrowLeft import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme @@ -112,7 +111,7 @@ private fun ItemRow( } is Item.Folder -> { ListItem( - leadingContent = ListItemContent.Icon(IconSource.Vector(Icons.Outlined.Folder)), + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Folder())), headlineContent = { Text( text = item.name, From ad3dac80f361f31b29f777c1b4f394afe107b4af Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Mar 2026 17:25:47 +0000 Subject: [PATCH 074/103] Update screenshots --- ...eatures.viewfolder.impl.folder_ViewFolderView_Day_1_en.png | 4 ++-- ...tures.viewfolder.impl.folder_ViewFolderView_Night_1_en.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Day_1_en.png index 9b53e56d9f..035b39c739 100644 --- a/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7983d27647e60d385703d5bb91763ab787ee69e0a0ef04acd13ca86d5d5b1ec -size 9560 +oid sha256:0cdaf746151224c1889c60232b55cb8c9d8b3c07cd341b1bb8ad6fb7abff97ed +size 9538 diff --git a/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Night_1_en.png index ced849e58a..2a46e52aa3 100644 --- a/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.viewfolder.impl.folder_ViewFolderView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c32280e645ff1459b179423f67077dfc75093f5e6c40fff659769d164f391aeb -size 9408 +oid sha256:072d91aa19fa0c5ec80ca565e1529988598cd54afcf6f593c6dcf17882170d0c +size 9393 From 25c0eb327fe7fd7a9cb1c93d60d099238e309911 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:16:30 +0100 Subject: [PATCH 075/103] Update dependency io.sentry:sentry-android to v8.36.0 (#6461) 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 da8eda2c9e..e14ac6890e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -221,7 +221,7 @@ color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics posthog = "com.posthog:posthog-android:3.37.0" -sentry = "io.sentry:sentry-android:8.35.0" +sentry = "io.sentry:sentry-android:8.36.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.33.2" From f3b155f4f7765a764af5d6a0c9b129ab673b4ebd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:26:24 +0100 Subject: [PATCH 076/103] Update metro to v0.11.4 (#6448) 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 e14ac6890e..324dc71d05 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -54,7 +54,7 @@ haze = "1.7.2" dependencyAnalysis = "3.6.1" # DI -metro = "0.11.2" +metro = "0.11.4" # Auto service autoservice = "1.1.1" From 68f64c3ae9dfb87d7dabfc496002796f3303e190 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 25 Mar 2026 09:40:12 +0100 Subject: [PATCH 077/103] Fix grammar issue. --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 039fc7b964..d33bc354e2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -56,6 +56,6 @@ Uncomment this markdown table below and edit the last line `|||`: - [ ] UI change has been tested on both light and dark themes - [ ] Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility - [ ] Pull request is based on the develop branch -- [ ] Pull request title will be used in the release note, it clearly define what will change for the user +- [ ] Pull request title will be used in the release note, it clearly defines what will change for the user - [ ] Pull request includes screenshots or videos if containing UI changes - [ ] You've made a self review of your PR From a4761b141fdaa816bfc0697569288c0090ad3a49 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 25 Mar 2026 09:46:08 +0100 Subject: [PATCH 078/103] Add question about AI usage in the Pull Request template. --- .github/pull_request_template.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d33bc354e2..95f322a2e4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -52,6 +52,9 @@ Uncomment this markdown table below and edit the last line `|||`: +- This PR was made with the help of AI: + - [ ] Yes. In this case, please request a review by Copilot. + - [ ] No. - [ ] Changes have been tested on an Android device or Android emulator with API 24 - [ ] UI change has been tested on both light and dark themes - [ ] Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility From 8fee1aba50014f8db65d6f9e84e8765cc3992388 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 25 Mar 2026 11:55:42 +0100 Subject: [PATCH 079/103] Create AGENTS.md --- AGENTS.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 119 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..454c347a9f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,118 @@ +# AGENTS.md — Element X Android + +> **Repo:** `element-hq/element-x-android` — Android Matrix client (Compose UI + `matrix-rust-sdk`). + +--- + +## Strong Conventions + +PRs must meet these rules. + +### Code Style + +- Style enforced by **Editor config** (`.editorconfig`). +- Set "Hard wrap at" to 160 chars in Android Studio. + +### PII & Logging + +- We use **Timber** for logging. Never use `android.util.Log`. +- **Never log secrets, passwords, keys, or user content** (e.g. message bodies). +- Matrix IDs (User IDs, Room IDs, Event IDs) are safe to log. + +### Strings & Localisation + +- Default localisation: `en` (en-GB strings), shared with Element X iOS via [Localazy](https://localazy.com/p/element). +- **Never edit `localazy.xml`** — it is auto-generated and overwritten. +- New English strings go in **`temporary.xml`**. The core team imports these to Localazy. +- **Key naming**: + - Cross-screen verbs: `action_` (e.g., `action_copy`). + - Common nouns/other: `common_` (e.g., `common_error`). + - Accessibility: `a11y_`. + - Screen-specific: `screen__` (e.g., `screen_onboarding_welcome_title`). + - Errors: `error_` prefix. + - Platform-specific: `_ios` or `_android` suffix. + - Placeholders: Use numbered form `%1$s`, `%2$d`. + +### Previews + +- Create previews for **all main states** of a Composable. +- Use `@PreviewsDayNight` for consistency. +- Use `PreviewParameterProvider` (e.g., `FooStateProvider`) to provide states. +- Wrap previews in `ElementPreview { ... }`. + +--- + +## Pull Request Guidelines + +- Use sentence-style commit/PR messages (no conventional commits). +- Apply exactly **one** `PR-` label for changelog categorization. +- PR title = changelog entry — make it descriptive; no "Fixes #…" prefixes. +- Include screenshots or screen recordings for any UI changes. +- Keep PRs focused; split changes over 1000 lines. + +--- + +## Project Structure + +### Build System + +Common Gradle tasks: +- Build: `./gradlew assembleDebug` +- Unit Tests: `./gradlew test` +- Lint: `./gradlew lint` +- Format: `./gradlew ktlintFormat` +- Update Docs TOC: `./gradlew generateDocsToc` + +### Gradle Modules + +Features follow a 3-module structure: +- `features/foo/api`: Public interfaces and data classes. +- `features/foo/impl`: Internal implementation, Presenter, and View. +- `features/foo/test`: Test fakes and utilities. + +--- + +## Architecture: Appyx + Molecule + +We use [Appyx](https://bumble-tech.github.io/appyx/) for navigation and [Molecule](https://github.com/cashapp/molecule) for Presenters. + +### Files Per Screen (`Foo`) + +| File | Purpose | +| :--- | :--- | +| `FooNode.kt` | Appyx Node: Handles navigation and wires the Presenter to the View. | +| `FooPresenter.kt` | A `@Composable` function that produces `FooState` from `FooEvent`s. | +| `FooView.kt` | Stateless Composable rendering the UI from `FooState`. | +| `FooState.kt` | Data class representing the immutable UI state. | +| `FooEvent.kt` | Sealed interface for UI actions sent to the Presenter. | +| `FooStateProvider.kt` | Provides sample states for Previews and Screenshot tests. | +| `FooPresenterTest.kt` | Unit tests for the Presenter logic using Turbine. | + +--- + +## Dependency Injection (Metro) + +- We use [Metro](https://zacsweers.github.io/metro/) for DI. +- Inject via constructor parameters using `@Inject`. +- Use `@AssistedInject` and `@AssistedFactory` for components requiring runtime arguments (like Navigators or IDs). +- Use `@ContributesBinding(AppScope::class)` for singleton-like services. +- Use `@ContributesNode(RoomScope::class)` for Appyx Nodes. + +--- + +## Compound Design System + +Always prefer Compound components and tokens from `libraries/compound/` module. + +- **Colours**: `ElementTheme.colors.textPrimary`, `ElementTheme.colors.bgCanvasDefault`. +- **Typography**: `ElementTheme.typography.fontBodyMdRegular`. +- **Icons**: Use `CompoundIcons.IconName()` (e.g., `CompoundIcons.UserProfileSolid()`). + +--- + +## The Rust SDK Layer + +We wrap the `matrix-rust-sdk` to isolate the UI from the underlying SDK. +- Naming: SDK `Room` → `JoinedRoom` or `RoomInfo`. +- Type Mapping: Map Rust SDK types to Kotlin data classes in the `api` module to avoid leaking `MatrixRustSDK` into the UI. +- Always follow Kotlin naming conventions (e.g., `userId` instead of `userID`). diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..eef4bd20cf --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md \ No newline at end of file From dca95e758d515c73db325e8198046b3516b7663f Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 25 Mar 2026 12:28:55 +0100 Subject: [PATCH 080/103] Add some instructions for features to the community PR notice message (#6465) --- .github/workflows/fork-pr-notice.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/fork-pr-notice.yml b/.github/workflows/fork-pr-notice.yml index 2b0431003a..af3e4a3006 100644 --- a/.github/workflows/fork-pr-notice.yml +++ b/.github/workflows/fork-pr-notice.yml @@ -29,6 +29,7 @@ jobs: repo: context.repo.repo, body: `Thank you for your contribution! Here are a few things to check in the PR to ensure it's reviewed as quickly as possible: + - If your pull request adds a feature or modifies the UI, this should have an equivalent pull request in the [Element X iOS repo](https://github.com/element-hq/element-x-ios) unless it only affects an Android-only behaviour or is behind a disabled feature flag, since we need parity in both clients to consider a feature done. It will also need to be approved by our product and design teams before being merged, so it's usually a good idea to discuss the changes in a Github issue first and then start working on them once the approach has been validated. - Your branch should be based on \`origin/develop\`, at least when it was created. - The title of the PR will be used for release notes, so it needs to describe the change visible to the user. - The test pass locally running \`./gradlew test\`. From 0aa1084fb3c59948361c1de3ae29db74e9bf60c5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 25 Mar 2026 15:27:36 +0100 Subject: [PATCH 081/103] Update UI of replies. --- .../components/TimelineItemEventRow.kt | 61 +++++++++++-------- .../matrix/ui/messages/reply/InReplyToView.kt | 13 ++-- .../textcomposer/ComposerModeView.kt | 9 ++- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index b253f45937..a814d8da42 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl.timeline.components import android.annotation.SuppressLint import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.draggable @@ -269,7 +270,9 @@ fun TimelineItemEventRow( if (displayThreadSummaries && timelineMode !is Timeline.Mode.Thread && event.threadInfo is TimelineItemThreadInfo.ThreadRoot) { ThreadSummaryView( modifier = if (event.isMine) { - Modifier.align(Alignment.End).padding(end = 16.dp) + Modifier + .align(Alignment.End) + .padding(end = 16.dp) } else { if (timelineRoomInfo.isDm) Modifier else Modifier.padding(start = 16.dp) }.padding(top = 2.dp), @@ -742,11 +745,17 @@ private fun MessageEventBubbleContent( } else { inReplyToModifier.clickable(onClick = inReplyToClick) } - InReplyToView( - inReplyTo = inReplyTo, - hideImage = timelineProtectionState.hideMediaContent(inReplyTo.eventId()), - modifier = talkbackCompatModifier, - ) + Row( + talkbackCompatModifier + .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, RoundedCornerShape(6.dp)) + .background(ElementTheme.colors.bgCanvasDefault, RoundedCornerShape(6.dp)) + .padding(4.dp) + ) { + InReplyToView( + inReplyTo = inReplyTo, + hideImage = timelineProtectionState.hideMediaContent(inReplyTo.eventId()), + ) + } } if (inReplyToDetails != null) { // Use SubComposeLayout only if necessary as it can have consequences on the performance. @@ -833,25 +842,27 @@ internal fun TimelineItemEventRowWithThreadSummaryPreview() = ElementPreview { groupPosition = TimelineItemGroupPosition.First, threadInfo = TimelineItemThreadInfo.ThreadRoot( latestEventText = "This is the latest message in the thread", - summary = ThreadSummary(AsyncData.Success( - EmbeddedEventInfo( - eventOrTransactionId = EventOrTransactionId.Event(EventId("\$event-id")), - content = MessageContent( - body = "This is the latest message in the thread", - inReplyTo = null, - isEdited = false, - threadInfo = null, - type = TextMessageType("This is the latest message in the thread", null) - ), - senderId = UserId("@user:id"), - senderProfile = ProfileDetails.Ready( - displayName = "Alice", - avatarUrl = null, - displayNameAmbiguous = false, - ), - timestamp = 0L, - ) - ), numberOfReplies = 20L) + summary = ThreadSummary( + AsyncData.Success( + EmbeddedEventInfo( + eventOrTransactionId = EventOrTransactionId.Event(EventId("\$event-id")), + content = MessageContent( + body = "This is the latest message in the thread", + inReplyTo = null, + isEdited = false, + threadInfo = null, + type = TextMessageType("This is the latest message in the thread", null) + ), + senderId = UserId("@user:id"), + senderProfile = ProfileDetails.Ready( + displayName = "Alice", + avatarUrl = null, + displayNameAmbiguous = false, + ), + timestamp = 0L, + ) + ), numberOfReplies = 20L + ) ) ), displayThreadSummaries = true, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt index dcf12f1953..0dc8aac09e 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -82,19 +81,19 @@ private fun ReplyToReadyContent( modifier: Modifier = Modifier, ) { val paddings = if (metadata is InReplyToMetadata.Thumbnail) { - PaddingValues(start = 4.dp, end = 12.dp, top = 4.dp, bottom = 4.dp) + PaddingValues(end = 8.dp) } else { - PaddingValues(horizontal = 12.dp, vertical = 4.dp) + PaddingValues(start = 8.dp, end = 8.dp) } Row( modifier - .background(MaterialTheme.colorScheme.surface) + .background(ElementTheme.colors.bgCanvasDefault) .padding(paddings) ) { if (metadata is InReplyToMetadata.Thumbnail) { AttachmentThumbnail( info = metadata.attachmentThumbnailInfo, - backgroundColor = MaterialTheme.colorScheme.surfaceVariant, + backgroundColor = ElementTheme.colors.bgSubtlePrimary, modifier = Modifier .size(36.dp) .clip(RoundedCornerShape(4.dp)) @@ -128,7 +127,7 @@ private fun ReplyToLoadingContent( val paddings = PaddingValues(horizontal = 12.dp, vertical = 4.dp) Row( modifier - .background(MaterialTheme.colorScheme.surface) + .background(ElementTheme.colors.bgCanvasDefault) .padding(paddings) ) { Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { @@ -146,7 +145,7 @@ private fun ReplyToErrorContent( val paddings = PaddingValues(horizontal = 12.dp, vertical = 4.dp) Row( modifier - .background(MaterialTheme.colorScheme.surface) + .background(ElementTheme.colors.bgCanvasDefault) .padding(paddings) ) { Text( diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt index ac64245668..3d7c4f810c 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.textcomposer import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -120,6 +121,9 @@ private fun EditingModeView( } } +/** + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2019-6286 + */ @Composable private fun ReplyToModeView( replyToDetails: InReplyToDetails, @@ -129,8 +133,9 @@ private fun ReplyToModeView( ) { Row( modifier - .clip(RoundedCornerShape(13.dp)) - .background(MaterialTheme.colorScheme.surface) + .clip(RoundedCornerShape(6.dp)) + .background(ElementTheme.colors.bgCanvasDefault) + .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, RoundedCornerShape(6.dp)) .padding(4.dp) ) { InReplyToView( From aee89c29e375d5eb9039d0cb2adba6d200f4258e Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 25 Mar 2026 14:43:07 +0000 Subject: [PATCH 082/103] Update screenshots --- ....components_TimelineItemEventRowDisambiguated_Day_0_en.png | 4 ++-- ...omponents_TimelineItemEventRowDisambiguated_Night_0_en.png | 4 ++-- ...ents_TimelineItemEventRowWithReplyInformative_Day_0_en.png | 4 ++-- ...ents_TimelineItemEventRowWithReplyInformative_Day_1_en.png | 4 ++-- ...ts_TimelineItemEventRowWithReplyInformative_Night_0_en.png | 4 ++-- ...ts_TimelineItemEventRowWithReplyInformative_Night_1_en.png | 4 ++-- ...components_TimelineItemEventRowWithReplyOther_Day_0_en.png | 4 ++-- ...components_TimelineItemEventRowWithReplyOther_Day_1_en.png | 4 ++-- ...mponents_TimelineItemEventRowWithReplyOther_Night_0_en.png | 4 ++-- ...mponents_TimelineItemEventRowWithReplyOther_Night_1_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_0_en.png | 4 ++-- ...ine.components_TimelineItemEventRowWithReply_Day_10_en.png | 4 ++-- ...ine.components_TimelineItemEventRowWithReply_Day_11_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_1_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_2_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_3_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_4_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_5_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_6_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_7_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_8_en.png | 4 ++-- ...line.components_TimelineItemEventRowWithReply_Day_9_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_0_en.png | 4 ++-- ...e.components_TimelineItemEventRowWithReply_Night_10_en.png | 4 ++-- ...e.components_TimelineItemEventRowWithReply_Night_11_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_1_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_2_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_3_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_4_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_5_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_6_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_7_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_8_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_9_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_0_en.png | 4 ++-- ...aries.matrix.ui.messages.reply_InReplyToView_Day_10_en.png | 4 ++-- ...aries.matrix.ui.messages.reply_InReplyToView_Day_11_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_1_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_2_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_3_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_4_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_5_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_6_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_7_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png | 4 ++-- ...raries.matrix.ui.messages.reply_InReplyToView_Day_9_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_0_en.png | 4 ++-- ...ies.matrix.ui.messages.reply_InReplyToView_Night_10_en.png | 4 ++-- ...ies.matrix.ui.messages.reply_InReplyToView_Night_11_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_1_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_2_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_3_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_4_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_5_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_6_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_7_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png | 4 ++-- ...ries.matrix.ui.messages.reply_InReplyToView_Night_9_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Day_1_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Day_2_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Day_3_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Night_1_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Night_2_en.png | 4 ++-- .../libraries.textcomposer_ComposerModeView_Night_3_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_0_en.png | 4 ++-- ...s.textcomposer_TextComposerReplyNotEncrypted_Day_10_en.png | 4 ++-- ...s.textcomposer_TextComposerReplyNotEncrypted_Day_11_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_1_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_2_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_3_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_4_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_5_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_6_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_7_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png | 4 ++-- ...es.textcomposer_TextComposerReplyNotEncrypted_Day_9_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_0_en.png | 4 ++-- ...textcomposer_TextComposerReplyNotEncrypted_Night_10_en.png | 4 ++-- ...textcomposer_TextComposerReplyNotEncrypted_Night_11_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_1_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_2_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_3_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_4_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_5_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_6_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_7_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png | 4 ++-- ....textcomposer_TextComposerReplyNotEncrypted_Night_9_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_10_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_11_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_1_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_2_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_3_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_4_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_5_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_6_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_7_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_9_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_10_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_11_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_1_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_2_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_3_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_4_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_5_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_6_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_7_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_9_en.png | 4 ++-- 112 files changed, 224 insertions(+), 224 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en.png index 70cad36fb8..c70050658f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6ff9fab1ba47c6980973ab630452ba495c48c8a3a8a729165d8e4b349829610 -size 378850 +oid sha256:bd81cbc3db5d329fcc1f0d4866c220af7488bb68929d0e75b983a170d15a7ab7 +size 380173 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en.png index 63c81718ec..57e2226f1f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f89057d77318350e25c3f77f805d94b0565c6da49d75c5a4ea5f720bc940639 -size 377421 +oid sha256:3be2bb0c8e344780d59b67a4ba23e50890b24a8b8ad1c48673e34403ff8db496 +size 378130 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en.png index 3545243654..662ccbf182 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df9a19fd97818a42de31abad719e3970c6f43ff5a5c9da18178d56055a77bff4 -size 364535 +oid sha256:da65fa129fdfe903f3e466f4e1dc6c70a6930e0388a3f6d3fb116e5b91411cc3 +size 365497 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en.png index 60c7cb350d..11289371f2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1841032c1263db6fa60fb623f22dfe403ad0b84feaaa805f22ee4ab4c0a38003 -size 369676 +oid sha256:cd797555bb72d7bc1b874df24ca5793df5550b235fe9a28d20aaa04bf5f3d0fb +size 370592 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en.png index 6b0aacceea..64bcaa05f9 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d1104ad18d9f1f3d1fdd8d06b1ad770e83683ffab1178cdfa39287ecc9cad2c -size 362744 +oid sha256:be969a809f346799887fe031e139dcc47db8bc851ca4ccfae8dad4ad9dc523f7 +size 363498 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en.png index 5632e96cc3..33ea565e67 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e338bf938a51a33a938bf56a7586f40027e6315a7274081d69ca1b7d90f4ac2 -size 367989 +oid sha256:48c0af64a6aab3a28ac0493bb86cb92424555d6793a0a5c6cd446c25a20ce915 +size 368757 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en.png index af596ec8bf..1a345fdd13 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc00bc0d3b8e39def6e436041ae33c7347590bd7db5593e971be1097fcea61d0 -size 352831 +oid sha256:9b4bef0095e989bd411426a2626155f1b75931f05c32d2632144f3c232f3aa93 +size 348379 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en.png index 0f49e8038e..7ef8d729ef 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7b737239c280a29096ed2e6baa119c0aa9ca43be19fc0dee4954421b1fd9676 -size 362812 +oid sha256:30db6503b7dde29553b5f806924565b1d60c13edeeaa982dd2ec7d2a5c8f1162 +size 364508 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en.png index 89e08bb36a..72f5c9a9e5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25c2bd1012f42aca6e26e507227a5c2124d467e1f5a53f904771d3ee04ea135c -size 351416 +oid sha256:15ad31eb2b457790913442d3186fae215f77f345470748cd64a345849b9de9d0 +size 346837 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en.png index 29b0433aee..5a6ad7fc23 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a460c547938ad02671120449143521416d7aa749933b9de383426eb0739dfc3 -size 360735 +oid sha256:2e72a79c374fc23a1325e1bd294584b8b7f0b312c804b932144bc2e5d8911bd9 +size 361950 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en.png index 32287d297f..ca682211d3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcc2ff819cc5ffc150733fb1d35d5c33980f3a02b64ba22ce1ff18937a6060ac -size 369227 +oid sha256:092a0d4c37d47c84c790a767b9acc77f38878876e609b986f80e5fb461e0a340 +size 370156 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_10_en.png index 422d500669..51a93f68e5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e0a453b674c183397bd7d73989c6076b117b77b76530ae950a880e1695b81a1 -size 354134 +oid sha256:097fe6208d9cadc707e6866c151a2ab843550a9fab4d2cf4908514ceafc4e396 +size 355327 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_11_en.png index abae0a9fc1..e60716fb3b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:188123a9bb96d0ef73bb155dc3483bf9b62beff19c09476290c2e41deb037539 -size 367454 +oid sha256:f61a7a62c6fc96e23c8aaa793f5fff68e2197a067ad8f1614d1103e833b3230c +size 368585 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en.png index f6cbf9e1e0..73be879502 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a18bd271f6b62f41b4444db47ed670556aebc35ae04fab5d7469584a693b355b -size 344427 +oid sha256:091352ebd6bf2abfac5dfd99be5edc94159a5a45c1d3137c7271e0031116a254 +size 345649 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en.png index f85a41dda7..4ec235074c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec95fa651eb1c0d4177a39cdb2edfa341836ef7f950e00859330092bd3377ec8 -size 356956 +oid sha256:842632747c13219ee6c7a50d9003c9e07c622393ae4b066e86eacf04f807b181 +size 358344 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en.png index ec431d5dcc..bc6cb62827 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab3cd83565ad087a616318e19bf61543a6b147526f5cf954ccbe9a74697e7b0f -size 356246 +oid sha256:4f43d615fd1aec05ee483d3047e99c1ecc89a6e5a7e56e6cf7e1ea4c108be413 +size 357473 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en.png index 15dd124ae3..d39b6ec114 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba66f3cf4dd43a7142313ded0ba4250a161f0ee81b69e49479af6cc6386782af -size 363963 +oid sha256:898a1e8f0277d43a1127d99ec50687c24fe1154ceb290832a14fa5a43f12647a +size 365153 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en.png index 3299e1b955..0617c06d2f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba8724c2426d9cde19b8b447adae49fa84b15dda972f2ea5ee14ec8753c5fb70 -size 396669 +oid sha256:4cce6211c0a33407498145cb03a780d80553983146f487ba3e26f794ddf12369 +size 397594 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en.png index bb57c7a9a4..838c70dcdc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a98bbc32b55663fb92f37d8137ced36796f8be9e6597df307cc5e70dc3c77548 -size 355533 +oid sha256:f7e91b7aec4c43e2028a2e69a02f66e04f6a3188a42387013e3deb1faa7a108e +size 356627 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en.png index e0be9f97b2..44e5341280 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c43a1fc9e46f5aa0cb3c7b16138eab590f3851bc2931d49a07e1ddd298b835da -size 354924 +oid sha256:80c2e99ce6f851994da38077acc30ff386867f2093a8db4de3c1b82b0b6c1a8e +size 356307 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png index bf6cbaadcb..6a0ee13891 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d7b628cc474a421869207c8ffd86e46c193da3e1fe8ea115fb12574528da933 -size 364172 +oid sha256:b4fd5470ac81fbdaf471e297c0f5bd9c6b9945e006ab88079568848befe1049d +size 365366 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en.png index cf0a527c3d..cede2d333e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:531d5e33349addf7274516915d58c7b71ee6f02c7775dcfdbdd5aac22054ef1e -size 354717 +oid sha256:a75fb4510d405b29b120fa400d4f69a89965c11a2228b5cc2e772200a12227e1 +size 355912 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en.png index dfe3285500..ebe440bfdd 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3573fe8bc2e46dd8ec7a1802461e25fe81f4997028f22da10588f786523a8a0 -size 367332 +oid sha256:a3f7e96bbbb4b3661514713514d7f6cb27c6634ba2621c22c0dd4ff730e5e24a +size 368043 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_10_en.png index 13940f7bbe..bd841f6f75 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab71afb3d5dc8091553a5691ad0ec6f29f054111f4f753a4b4e1ce69804a5295 -size 352399 +oid sha256:449cc2fa5ce39163a5d5eea3430c7dc457579d41b0213b8b46a61acaa76b3ccc +size 353304 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_11_en.png index 0024d09ff8..2867c5dfd4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1dd9be6a617150efa3e26eed31adc31a91a9daf698ab1a1e720d98e946f00696 -size 365708 +oid sha256:4cb93499ea8f21d3fb79aa81b2746972f57a4732296bb421897e93a47ddf7d06 +size 366544 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en.png index 6e5f39b2aa..83d0f043e4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:036665adb2b62bc19fac69180a6d9f3774831daa65993cadb49f9e0db67c50a8 -size 342324 +oid sha256:a6bb6a35c2e1d2090e6e6e5b3a1733d16fd433e63925082b2ea32293ecc639fd +size 343140 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en.png index 5c6c6874d5..e178f75d91 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0894fc410211b804f62d3cbaf717443b3f91661bb3adc0b317d94bdd020ea2ad -size 355530 +oid sha256:a1067826b5b1e3220eef3ee3b9a8c9f77bebb248ba2378cc2e7029b86c585c48 +size 356339 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en.png index 7cc5d83e7b..f43199a9d8 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7311e62cbf34246e18a8cad6dd9b66f79d5a97bee7a209cf436f27df77c31c4 -size 354658 +oid sha256:437f71e1845447b8f09905b4d97dd46677d8d8db669a317f8cba9ada6f5f1aa8 +size 355551 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en.png index 50421fffa8..80db679074 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad2e5231f8aa2ece0bcdf7cf11d01fc02054591bceb954db5bde776982b3a993 -size 362278 +oid sha256:ffa5216fcff101f8ab1047ac9808f98749144e1b1197bc01905cd6ad251d31b7 +size 363081 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en.png index f19ffbc4f7..b7a7e2020b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2fc2bb23a0d904e8b8a60e3911c5f39c1623816ab0ffc5282f794ac84dad55dd -size 394921 +oid sha256:222460ba0557c96c2ad0e8aab675a254f515281d06bf4a7b642ea7ef79d5171d +size 395589 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en.png index 05df91e738..75bb1086fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15765ef6c94a2705d3c522d0bafc5494dcb182ec1fd096e4cfd2ead49f9e19ab -size 353748 +oid sha256:bb0a738e57b657bda2454526dcd78a37d38839183a5feae99bf7f107c12ccded +size 354661 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en.png index e6f7683c55..a93768052e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6f679df9cbe470096c5f939a1781973586fd9afb2d76b634c4ccc47180c7afb -size 353506 +oid sha256:7f98146a417290fcc741ef676fdb60f36822931358e943ad12faace7f96e995f +size 354422 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png index 38499a5838..c09d98903c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b9a9264b6637a35096b2f552a2dbe9f6fa6a078bb631c17bf1d207e10928f07 -size 362463 +oid sha256:54c9d1f121d83f1a161f6483a6b4bbefa220c235ae88097ed4d03baf10bbcf9c +size 363289 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en.png index b590ba1a5e..0e2c06b0f3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b144eda9c14fe696ad81309441181008eddeeec7c6b4aa4cc3b2b7c702ae6539 -size 353091 +oid sha256:932e5b29f2a64d70956470bee1be397775c6205f590081d3b90c98cf47845577 +size 353993 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en.png index fd8c973b2f..b2178a98a8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:831fd682ca73c8e76f63d6b504f1f48bb23a26f2c4b706764d9d10e3fd9408d7 -size 10345 +oid sha256:319efe6fe21e61125e9f935a13724ddab6ba6c8ae21c7d21bd70470c3a22989f +size 10275 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en.png index 57de8c7c5a..e19875f9b0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7a5321def638da7c0be09583cb2f1dfb426b72391101649499c50654b583ea7 -size 6047 +oid sha256:7732d4b601ddd133a4b3ae55cd89924a7b12fffaf2209039c92594176b6d4b7f +size 6094 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_11_en.png index fc75f53313..6e3ce81929 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96dd2df2b23af067aa88b042a8630ec90a3f97902a1633cb7549a602703129fe -size 9958 +oid sha256:f20f580ef41bc793db8de7d68dc32ca40a4a1208888211bd7985401aeb8eb887 +size 9933 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en.png index 86a1004473..c2427f09ce 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fdb88a54b6d4b4cd63f82c378a130f5db142826ccb8639e76f50e3b0c40b591 -size 19131 +oid sha256:21ed68f52eb3491a6ac8afa8ea30a1b30b85d2d8e31b55435d4b54c50ba7fa22 +size 19086 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en.png index c0a8409f4a..ce1aa75dbd 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:910497ff71ac4339d7d74a5429adad2f433e3e013eba029bcdddf7a19d5dc7f7 -size 6995 +oid sha256:4c7b1a09703340606e5bbdd04b40639eb9a699eacfc13544c68cc023911b00ed +size 7036 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en.png index e674aec88f..b8be38269c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f63e794327c94cb5ac33a4c6aecfefecd33061d7dae11b0ec69f844d26760c5 -size 6751 +oid sha256:3f12bcd2d9f3f7886d18af3a2744d90ff404e31d76f5b639ceafa4a56def6b8a +size 6742 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en.png index fdf537d713..edb7b691b1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52dde3608560c4b9d72f77369bd118cc0afcdc975980e034717be191bd77ff87 -size 8879 +oid sha256:1bfa60a6f0c11fef5b2495d0c6eb7f8ee1307f1b0e26c5ca011ae42974f58a25 +size 8876 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en.png index 6efcfde23c..26feb79b74 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a31373ee4be724122839f9d9d7dbed0727a5f75a816f76edb962d107a281bc42 -size 17804 +oid sha256:3d2d4a34cc7b6dad27e647d8621611327ca44dac4e06a94275c8eb3e3255640c +size 17483 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en.png index b54cd19be0..cdfdcdef46 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d1ace89822dfcde7822bc2412787290d64094f6ee82afcd4247fa3bac36067e -size 6464 +oid sha256:916fa670e5d86b765b01a4304ea57871875170f9d98d148f3c0a2aa2c4c5d32c +size 6431 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en.png index 10e2663ec0..bb4ce4a2ba 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:817085c720aa5106231462bdab94c3a4bded7ea64285e42123c2972fb1492c5d -size 6416 +oid sha256:b4dd558d07a5c122615c6c733532d46db3989d4f1fa08a0df1dc78fd9079111d +size 6439 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png index 789e6ad754..7dada9cdd4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:936f352e9c70919e2f5d325dee2eb3048b625e77bbdc0ac1685d023c131a7cb2 -size 8977 +oid sha256:edfccd98d79cdd1f16c6d8068a54b752d29f52e7b5cead52addd24bff6be3e6d +size 8966 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en.png index 511ec6112b..6d0d14ef53 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd9e3f62c47e3cabeab49a3ffc6cc4ebde8c5baa03c5997dd9796a2eec3fd420 -size 6297 +oid sha256:6868dab8f078724ed45df7b8f391a205ea373bad58d80e33d8299e279e063a33 +size 6317 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en.png index 38469923aa..095a3410bf 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b6bf627769f2bbaa1c76142e7f17f5c7d5b8c3e1029cad3d498085d0764cfe6 -size 10035 +oid sha256:72cb0735391078279290f06c187c910d0929f3de2736aab5426ca3265f2088d0 +size 10018 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en.png index 4de0e3dfbd..87fce6f844 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61171fff9c238017712540f8af20e75cbfb4a2a5e87419a43f3332bc38088f47 -size 6027 +oid sha256:93c0b838dcb60c3a5ccadfa4ef821a3478dfbc541edaae767f33ff25bb2841ca +size 6018 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_11_en.png index 5e3ac6761f..fbf2c4fed5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:672eb3e8dc52f074598d0425b039fb829649efc91c4eec741a836fd850c38b6f -size 9740 +oid sha256:7b38b70e42547fde8c3a291b82d15aeeed46061a6d35d7ba1bc84e02f1772aef +size 9708 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en.png index 80762319f3..5d4b40749a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:361324daf490ded4331db68f8891b4fd3b36e6aa26b1436df3024aaad7c2e5d1 -size 18454 +oid sha256:ecd7d668dc9fe5442cad662bef3f27d854c11f3f186d35da9c8f8f59e976e584 +size 18424 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en.png index 283f6b60a7..be2b979a76 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e4b543edb49c9d8cd38276ecc28d425a9baa50f2e87ca900586341d1275f52f -size 6943 +oid sha256:3323b411015fe4cab91a492c33db0ded076d69a8327a91af956472f529662130 +size 6932 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en.png index 43eed1e235..f96a9ea58c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c53797fb625f7aeca30c11204f29afa45f235f652a3af4d92efb9415e5578d1 -size 6692 +oid sha256:bf1ff1acd363de8d5055a10f389f4542798bfd8cd72502cc21caef193eff6671 +size 6672 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en.png index d72c6927a5..d52f37416a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8243879f43ea8e6709b93292582748448e6a4ed55bd2d6e71aecb0788a2c98f4 -size 8697 +oid sha256:e0094eb0a7870ef9f703c10b90c0d03a9ac9e86c0a70875dc025e63c89e9ecbb +size 8704 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en.png index 6f652cf7d1..26cbd5d0e9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd154b4458a13250e547b5d4d48cbc05901024abd1add7497087ccd6e1e2163e -size 17601 +oid sha256:ed3dcc9061307803439cebfb2903a1778435e01cf6f0e0f35df89f82a1e9160f +size 17325 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en.png index e6aa19ef86..a934693a97 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48ae21d563c8a8b0793fcee2ca31e10e1d5f27a337d86fa6cebf40a33fff335c -size 6370 +oid sha256:fa841c96088cb4dc2998254a75acb61399301b175f547e7ae69886709ae8b2f6 +size 6371 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en.png index 4434ead741..1eb7e6614d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c1afc8b6bfa23e9ed73413078bd487c5557bc8c26717cef6c940cc6f0edf113 -size 6385 +oid sha256:c6d6286677b18af00e1a9b1198f0ae9aed929be74bbc122d051d867a51f373a6 +size 6358 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png index 8220e6b24a..57ff1a49a7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8799ed0f6c481130b4f1e3b5ff2c47148e84d5d26aa94559643b82f6db5a3521 -size 8756 +oid sha256:d8c926148b9641484885d6ccabbb54966f5e67a2d9fca609005d8ed8ad7d15d3 +size 8747 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en.png index 4df564660f..b6e3e269a1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:faa63783632a02ad15b8685d7666f3cd690d7e4507cb68bc1c3e2c04dda37af1 -size 6232 +oid sha256:63edce0142c410df6cace76df14e545b0b9c93eaacdf6707b01c2b16bb78a168 +size 6244 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_1_en.png index a5dfdf516a..a5db879ab2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e487991c578b7e3da4aa85c6b927716be10427c13db9ef65c2b784358f8f3eb4 -size 11276 +oid sha256:9775ee85b895e1eb6b58841a5232de980f44bf4a20c0f2e2bcab731f503fc762 +size 11000 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_2_en.png index face9cac29..c186a409ad 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3434cec9678fed9ef856f82ba8c403ba4f910d2997d05b7c2ffa9c71e5e73d1 -size 18588 +oid sha256:d7ab6bf5d8255d61569c4400f5a911400f415a4e228de41e181ccb42e2742e47 +size 18637 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_3_en.png index e10dd2f7f4..c229dd85d8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df36b9a00bc8cb59b12d679dfb6f64da43e77c7dd623fa60b6d4b29f7e00009b -size 7936 +oid sha256:8c54410a3733a3cecd1b161eb524e1809c270b8d2dd814c095eb73e013b486e0 +size 7840 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_1_en.png index ef2f8bf31d..609162f4bc 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0e7a2ab84947138437d1cd523a1a00778b362c9bb48679d6d15f1c8f1e10f9d -size 10841 +oid sha256:793eea182afcb72be59a090d3c3e622edcd6f9509271bef2e75a2f45f47a8fe4 +size 10567 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_2_en.png index d103fa0c98..874da23636 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f53060ab0874d769da5864efdb8f4cae2635fcaaffe95444094351941c904f80 -size 17941 +oid sha256:5e1cd401ab146d2d15e94a591625ab40440e32030f4acfd4ed9bd18dce01a1f0 +size 17814 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_3_en.png index 35d047c438..c4e3bc9a39 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_ComposerModeView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13ac54e860b1fdc289a90b89f78ad898a87c0bdf402d9055872e9974dda1c94d -size 7738 +oid sha256:0e47e98d0ace1eb50dfeb9935c27206abee28d42d0e092d410de4239dc6ac293 +size 7519 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en.png index 9a10ba343e..b51a04e421 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ebbb431d291ee5dd9cdb626e5a14c234fd3ae2d1b8d8b969f2081c6b27440d7 -size 72150 +oid sha256:2cf5e60d289daa62dff1c07469227acffd275a1e4a3534b60cbe37c89a2c4bb7 +size 72136 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en.png index 0808659fa8..217b3181b7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ac337c3f7c15411f092cbf0e2da541ce27f45d3e6a0f0eaa68d76382765030d -size 58752 +oid sha256:af4895f8222d984437a5d7427268d198345ad690161789d7bbb0340eeda916f7 +size 58660 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en.png index 7fabc79733..046d651b57 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95f41eb15d088c3b0dfc88d4f45a3cd094e6b649254db96dc791b37c0bd56823 -size 71559 +oid sha256:6049adcc9de51802804d0224bd7d5a7ee8ae2a754411e4ca5685df8028d51480 +size 71727 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en.png index 250616700e..26ba390595 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6bb5cfce24bb00859ba0108dc22a2af4855088611a28bff59d200059c966c7f6 -size 80168 +oid sha256:e339b203a782f7d73195b1cd6961c67dac8b313a6a965515e4bc2d2b83a2118d +size 80524 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en.png index ff20a49fb8..0a18ae1074 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ff3edf3e7a06d78070eb60ac005811ef7a36a7e588ad7054908add73600de05 -size 61262 +oid sha256:22cf555cb18cea56f2e6bd9f91dbf70353916f196ceba84b11ea017b9e95d794 +size 61511 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en.png index 5f5af0a341..063006fb88 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5eb7dc42fda918bdf0023209e1fcdedacd17e963d35d02130c909abed6582da6 -size 60178 +oid sha256:de1e98fb04a4188e2c6b795a3cf0b21129d0e99f8ea2748137e9f8122d413c6a +size 60353 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en.png index 813344a666..9bfef2c6a2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23cf73c95fec0934219c5c7921978189a5a12741a49255129774e3b0cde66a51 -size 67141 +oid sha256:1861fe30f2c653911cfe193d69c21affea73f458132d6a1b6381aa504d4cce74 +size 67327 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en.png index 454b45ec06..dcc6b6c915 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c836e3db5e6debbf5961cf56d00ca38ffe7105c150a65b23cffda79a893b2c2 -size 89141 +oid sha256:9b5f1d42f06c4c5949f1fb1d216c7af45c4606a782178c21b58d0a0e7504a333 +size 89006 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en.png index 4ea874b253..df1c374209 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:084829afc78b9072384d7c9d399e13a6246446705be78a07684c5c11497f5dd6 -size 59592 +oid sha256:f7074c637e0a3e9320f86a4f417931d59c2d5e199996e8e533f692a82ab0d8d2 +size 59581 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en.png index 35fc3774f7..442ea4ff99 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c8d2baecd4a076de262ce2bfc2f223c8e95adb33e1dd2e15c116674f8674735 -size 59533 +oid sha256:a0f084ce1bca37f796e7f50d78a4f03485b77fa742efd688d6b8accc2b41f5e9 +size 59734 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png index f7398ae396..4e4fd5476c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15256a6b4d1fe8e52080b9726cde401944cc6941f7527db1d18484c86ec88023 -size 66699 +oid sha256:20f92a0cbc8a60bb057b131e17300653ce21367627f611193b6b9ddeba5d4b37 +size 66908 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en.png index fe65732853..c5324db3d6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6712e76fb96f7830d48d4a1e276d42a20548a1bf425ce8049b55e413462741ed -size 59161 +oid sha256:3a0be3b08f1923c223eb433cda9d8c1bd86ba2dff1bce31e069b29953b13a084 +size 59085 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en.png index a839235a65..8fb1c22b45 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbc055122bb58e8eb0b0972ca52e1cdb181ef3afd2357b80c2bc24e72dadc245 -size 69227 +oid sha256:17bc1cac4537bd0b9a2dcd91838ff7c20de7e6076dbb9b174ad801af76f234f8 +size 69080 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en.png index b15f640a90..c6b221f461 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b5c0b430384e644e82c84581d04a36483cf41dcf6dd625c0295ed95dfe3f034 -size 56269 +oid sha256:caceabb04420f3675940e3b95ec685cb2b02c69d87fd19843640a5e882dfa1ca +size 56124 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en.png index 37bd4f7226..b5e644918e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:902a758672768adc02266bf0227aaf692e8f1d1aba91ba96be985caccdfffd22 -size 68668 +oid sha256:d46716354df7925d15345b61d8e16d80c0b3552b687a896004f4174286ad18ef +size 68625 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en.png index ce2458cb2f..c2bbd56d35 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f777e7d5aca4d2c1a7d2ecc956bf1a354f330f24c5092559ba59f305473cb227 -size 77106 +oid sha256:6a0b4ad61421f6b142e51200fb40df935027962145fa09b9871a11cdfdea8c0f +size 77316 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en.png index 8fafafadf8..3bb5259f05 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37f5275fabb3ec2cfa3efd533b52dbe4366888886881ad3a659b00aec867660e -size 58728 +oid sha256:89b7d536f86c72378714e4fab14b24671a86726abdcd63a1e15abcefde6a6abb +size 58721 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en.png index 9e0f64a82f..4af97d2cc8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46ad6c535da1d483b62f8b573b329a55fb8b15e9319e3d112299d2ae7c507877 -size 57694 +oid sha256:d314aa8f8572a099c4aa0f96de8dfade75c57edee4732c3d1300e5356c0bed20 +size 57649 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en.png index 28d8e0a2e2..918c7fa1b5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf851692c986a98e8f7fe989bd691099a8e9cd75da3d7977e84cdc22bb8aff7e -size 64468 +oid sha256:cf3bc1027fdbbb194d1a0120123872f0ce75c41c43d5c73c72908ddbffaaebb1 +size 64314 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en.png index 9dff6bedcd..c5eb73aa1c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dad1c1d9ea123fb417553f399cbaa27525c0e4a20a214fb0f81144e5107aa90a -size 85479 +oid sha256:92273288bdfe895fe0664533f60e322893ece33d271259303e35d9358fbae5df +size 85238 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en.png index 8a42433377..4449d490db 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea6929e35c476530c462cd4d2ff77d294044e3a5fb2133fe77d91339093ef71f -size 57134 +oid sha256:d04a904fb5f98c075ed844668a06af29d03e7d1adf8bab7706d1cea39abcceb6 +size 57003 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en.png index 53d7cea25f..ff54d6d0c5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a72d17f9c9abd2aaf9a074eee0955bbb3a2ffeb132f680abbfae0dee5d281a50 -size 57200 +oid sha256:896b4497818ded4ce18ad6089fd436160f87189d79da1cb63ea652818de10041 +size 57009 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png index 9bfed4fc61..6d72c0f7cc 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7c95c91b7c6b04f2851df6a64de1b10c7338a4d46921a90037fe50cd7d49262 -size 63957 +oid sha256:256349593b50a7e1f40db6c032aa39a640136934eadde8883936b0b1885f81b0 +size 63867 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en.png index a9c97db0ff..f05bee7bd5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:465cdce0b01b0044ab9b329629214171f39533f6219d0e7871176899c14df1c2 -size 56721 +oid sha256:25b5d39992361966545a3c04b3de7b20569a1e12800b3ecf38e090ceb2afa7c9 +size 56567 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png index c924d012b6..d9d7e2913e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5124db3fec69ba2ba44bd1ba2e3c7c7f861412637b62de2d4d741c7408ba111c -size 73253 +oid sha256:bfb2c4674cd8bd0bcd434a2790f3e121dbc6a6c39e41d0417c80cdfb44be91ae +size 73627 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png index 7e57b26400..7891573b3d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10874b3704e42faf8d77661a635551e4e685be1e17cfc7e963633cec8040c9dd -size 56785 +oid sha256:be931ad71b0562cd96456124c987ed79709f3ec7c55d736f4f71da1fdb036309 +size 56863 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png index 186f3dafc1..2e5b1dc647 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5f14eac2b49c3ba72ed9b9f6cab21c07a3c1b500e677c5353a5519ac9cb9077 -size 71491 +oid sha256:f3f24723f76f444a6503ee01399298ae4258a190cd6657dd1bf5308ea528d55f +size 72035 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png index 33c260415e..584285c1be 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d9ee6fa66bcd2b8f897d2f357c995f0f8d0d2fbc44ab0e8122e0cff17f7f86a -size 82796 +oid sha256:cfb33cec43d32917cb8f59e012244fa0c8824421cbedac516e002862f28f93db +size 83506 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png index c22d0bf38d..7414d959a4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d89ff053d51eb36a5045768ddb45763fbac67829ac256dd02661e8a8dec5c2ff -size 59808 +oid sha256:94d01e112a860c145c6c09d1d3a9bf948fe73e7b939d7f602704a3b4853de9f5 +size 60076 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png index 643aaaae5a..b6e7b4e2a5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb61501a314ece736f32ec8cc5269e315f2cf3a575e7b0fb3f604c5ec81bec34 -size 58928 +oid sha256:b064ba533e8bfa225f0548fc6e13d811a0ab0dddcd500cfbb72ed199a268c1b9 +size 59202 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png index 0bb7225a8b..c223cabf8f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf792e65d65749463ccc1b0a9ea41663b91d105fdeda1ad5498b4448b4b03e6c -size 66820 +oid sha256:8e0cdd88f5776e92aa0063c09f4c7c1c099d2b8cb0f4a13066925c1ca105b37a +size 66800 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png index 63b4246e64..042c2792ce 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dababe75d96905a844b9ef72d03ec378b70549005951a654b3d792ebd138d40e -size 101772 +oid sha256:fa0e313a3d429ddfba85b62f4d855489cb5cca62bc6693dcaa33f4d0ac622b85 +size 101888 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png index 32494f9b02..d1b0e795b5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b24c435152a26a2938a5774c91e819acdbd901c75b84997849f477ebb2ddc91 -size 58148 +oid sha256:3e3210208348505b93f4d673977f237bd7859b054699c1d66ece28591d20640b +size 58145 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png index 550543f30d..a014be7a5a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:add4c86c01e81b25f55aa6227533f6be9054f2cb4203cfd39ba6103494d3e640 -size 57748 +oid sha256:a0c9e887cd48c5aee046649a2ca5949abe763363659e29dd523869dc615e98f2 +size 58186 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png index 8e397b024e..4f07ac8b8f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27c823be03e6721a4034cdc4827a4d3dd34ac3e9d567651a8ce125cef435b57e -size 67151 +oid sha256:d5febf4de05a7794160b567dec3b00e818a6e3d4d7830d3dba97f72498aa5a3c +size 67172 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png index f99d139fc0..2d5e2c39da 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:882ca19a5e503c3c1143631760dcd061c4fecf313d55f363e3a4c7b9c693ba85 -size 57530 +oid sha256:f213b779238ac8536e4f0115d8de444a21c3b8ce31aac8aebd5415d8f80504a4 +size 57501 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png index ba74211c85..362033d451 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09d81b818719edccac051f7702d873a7e5464fe80244f8d6976648eecfd36b87 -size 70429 +oid sha256:27cc53e2336c9ccf90d97d2aed98f94f83315dcb9fe4bd489958b8df2366262c +size 70207 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png index fba3827ccd..aa712c48ec 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9027508487f18ad1c74a48563bd9997aeb49f500f4b5f272e095afe0d38b37a -size 53999 +oid sha256:bd6c1a82daedd923982d81956924eeaa37857d54dee55f31fda4520071b4f66b +size 53675 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png index c37fdc1ae2..804b238d8d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d25030399d0eb11d36f75338749689386e00a5100b0d4e9f05f61da5c16ce82 -size 68635 +oid sha256:ffce97ff7f1d6a2641d761aad6457883babe333075a454b5860d266719bdb3f9 +size 68525 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png index a83a48693d..ec221ef43a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44d6e39f26502a062f4d2bedbfde36e0010e2090c2a96438cca520a188b4e09d -size 79673 +oid sha256:58718344783197c680e18a7a3c97a3531293b6e2442ca5701d4605ecb567e70a +size 79724 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png index 31307b1de7..8369183006 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01358cf77f574e16c535b58428392a620b7a1b973f8135bcc7acc9cd12993686 -size 57325 +oid sha256:3d84207a6b1bf4815d2515974c721a0ba26fb406a31e96f3566b90e548c7bf49 +size 57077 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png index d3c00bfc0a..7cd4c1a580 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9209a8927ba2d25ce458f9acad040374d4818188959a654a52e62e81ba81da01 -size 56423 +oid sha256:2056d90bbf2676fae7d88b326c496aae95a1c31924c8b5d13ca363f486c72968 +size 56206 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png index c293a6ffdc..6b23cf2db8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60211550a5c617e356a775fbd3daffccc06c4d2992e30bc7c38baa7a18babf37 -size 64104 +oid sha256:5bca7347130b0b449ef2c917359753660446e4be7d2d4a13323489c63dbf28a4 +size 63589 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png index d12a76713d..f388e96dac 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d4e115598bd789d164ea1374cc761cf8391a7db658a29207e2f221dac678b62 -size 98295 +oid sha256:4fffdb6a8f159af3104d9f2e8edbc11395854f6ac6a558e303d20c79ea91857b +size 98128 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png index 16c70226c5..37890657c9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4c0053dcd73fadacfc2ad73c8e57a60e3c5f2186f1f83c083d08cf542e977c0 -size 55536 +oid sha256:534628991ee750aa4f4b4e3edda1ea26cf648eb74d06610d4207266b659d4421 +size 55083 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png index 3c9852479c..cb402d830b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38370c8eaa97e996514e9020f1d7dd6e8d1f87a66d99448f71dd531c0a158d5c -size 55352 +oid sha256:9de6ef77a1d574da317c3d1c3258f3068e79613387d0bc32e925f516338da9e9 +size 55092 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png index 0654617bd7..06a6ee8488 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:947ddd34efb97e8baad91a1c2865105190a7be599327a271db0466f4a86bf092 -size 64326 +oid sha256:350c89c3491e08a80f9910121140d56f2cf28fdc0b8f6ced380d1ec34b116c52 +size 63975 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png index 33d2768e08..e698f48771 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a4c884e8173cc9e031faff3da8c18c9411f5e39c9a56ad82941a36a4bb8381a -size 54795 +oid sha256:8659bbb89e5c26caea7f1d759e1c9bbd6ecedc525dcc2cb6b1cc844c835aeec1 +size 54455 From 0b7fe2f10dd075a5c3879ecf95a6febb70bce34d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 25 Mar 2026 16:51:41 +0100 Subject: [PATCH 083/103] Cleanup --- .../impl/timeline/components/TimelineItemEventRow.kt | 9 +++++---- .../android/libraries/textcomposer/ComposerModeView.kt | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index a814d8da42..c9bc130905 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -745,8 +745,8 @@ private fun MessageEventBubbleContent( } else { inReplyToModifier.clickable(onClick = inReplyToClick) } - Row( - talkbackCompatModifier + Box( + modifier = talkbackCompatModifier .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, RoundedCornerShape(6.dp)) .background(ElementTheme.colors.bgCanvasDefault, RoundedCornerShape(6.dp)) .padding(4.dp) @@ -843,7 +843,7 @@ internal fun TimelineItemEventRowWithThreadSummaryPreview() = ElementPreview { threadInfo = TimelineItemThreadInfo.ThreadRoot( latestEventText = "This is the latest message in the thread", summary = ThreadSummary( - AsyncData.Success( + latestEvent = AsyncData.Success( EmbeddedEventInfo( eventOrTransactionId = EventOrTransactionId.Event(EventId("\$event-id")), content = MessageContent( @@ -861,7 +861,8 @@ internal fun TimelineItemEventRowWithThreadSummaryPreview() = ElementPreview { ), timestamp = 0L, ) - ), numberOfReplies = 20L + ), + numberOfReplies = 20L, ) ) ), diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt index 3d7c4f810c..15aabdcbb0 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember From 1e53ffd086596c3e6e88a307dc20fdc882cb0574 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 26 Mar 2026 11:32:40 +0100 Subject: [PATCH 084/103] Kotlin 2.3.20 --- .idea/kotlinc.xml | 4 ++-- gradle/libs.versions.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 5be13229a7..76f6344777 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 87a7670c12..a8ca47e959 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ [versions] # Project android_gradle_plugin = "8.13.2" -# When updateing this, please also update the version in the file ./idea/kotlinc.xml +# When updating this, please also update the version in the file ./idea/kotlinc.xml kotlin = "2.3.20" kotlinpoet = "2.2.0" ksp = "2.3.6" From 2c083a87d4008c5d1a5a9b00a4f1d82ff6de5f74 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Fri, 27 Mar 2026 07:36:48 +0100 Subject: [PATCH 085/103] chore: update the build-rust-sdk script (#6476) --- tools/sdk/build-rust-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sdk/build-rust-sdk b/tools/sdk/build-rust-sdk index ea1b80c469..b3b57f7e98 100755 --- a/tools/sdk/build-rust-sdk +++ b/tools/sdk/build-rust-sdk @@ -228,7 +228,7 @@ cp \ if [ "${buildApp}" == "0" ]; then printf "\n## Building the application...\n\n" - ./gradlew assembleDebug + ./gradlew :app:assembleGplayDebug fi ## Clean remote checkout of SDK repo From 8239a5ba0af6e1d58c0d934d179adb7a1644e28e Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 27 Mar 2026 07:54:27 +0100 Subject: [PATCH 086/103] Fix `ForegroundServiceDidNotStartInTimeException` (#6470) * Start the `FetchPushForegroundService ` in foreground ASAP. This is a first step to mitigate `ForegroundServiceDidNotStartInTimeException` being thrown. * Don't stop the service immediately if it's running but not in foreground. Try waiting up to 5s for it to be in foreground. --- .../push/api/push/PushHandlingWakeLock.kt | 2 +- .../impl/push/DefaultPushHandlingWakeLock.kt | 2 +- .../impl/push/FetchPushForegroundService.kt | 57 ++++++++++++++++--- .../test/push/FakePushHandlingWakeLock.kt | 2 +- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/push/PushHandlingWakeLock.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/push/PushHandlingWakeLock.kt index 2b19ed9225..5c76eb1864 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/push/PushHandlingWakeLock.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/push/PushHandlingWakeLock.kt @@ -22,5 +22,5 @@ interface PushHandlingWakeLock { /** * Release the wakelock. If no wakelock is associated with the key, this method does nothing. */ - fun unlock() + suspend fun unlock() } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlingWakeLock.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlingWakeLock.kt index 1388aac19b..9713110042 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlingWakeLock.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlingWakeLock.kt @@ -31,7 +31,7 @@ class DefaultPushHandlingWakeLock( count.incrementAndGet() } - override fun unlock() { + override suspend fun unlock() { Timber.d("Releasing wakelock used for push handling.") FetchPushForegroundService.stop(context) if (count.decrementAndGet() <= 0) { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt index f0f4ebb2de..d7cc950b99 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt @@ -7,6 +7,7 @@ package io.element.android.libraries.push.impl.push +import android.app.ActivityManager import android.app.Service import android.content.Context import android.content.Intent @@ -25,7 +26,12 @@ import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withTimeoutOrNull +import timber.log.Timber import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds private const val NOTIFICATION_ID = 1001 @@ -51,11 +57,13 @@ class FetchPushForegroundService : Service() { } } - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + override fun onCreate() { + Timber.d("Creating FetchPushForegroundService") + bindings().inject(this) - wakelock.acquire(wakelockTimeout) - + Timber.d("Starting FetchPushForegroundService with wakelock timeout of $wakelockTimeout ms") + // Start the foreground service as soon as possible val notificationCompat = NotificationCompat.Builder(this, notificationChannels.getSilentChannelId()) .setSmallIcon(CommonDrawables.ic_notification) .setContentTitle(getString(CommonStrings.common_android_fetching_notifications_title)) @@ -65,6 +73,12 @@ class FetchPushForegroundService : Service() { .build() startForeground(NOTIFICATION_ID, notificationCompat) + super.onCreate() + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + wakelock.acquire(wakelockTimeout) + // The timeout is not automatic before Android 15, so we need to schedule it ourselves if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { coroutineScope.launch { @@ -86,10 +100,14 @@ class FetchPushForegroundService : Service() { override fun onTimeout(startId: Int) { super.onTimeout(startId) - pushHandlingWakeLock.unlock() + Timber.d("Wakelock timeout reached, stopping FetchPushForegroundService") + + coroutineScope.launch { pushHandlingWakeLock.unlock() } } companion object { + private val stopMutex = Mutex() + fun startIfNeeded(context: Context) { // Don't start the foreground service if the device is already awake val powerManager = context.getSystemService(POWER_SERVICE) as PowerManager @@ -107,9 +125,34 @@ class FetchPushForegroundService : Service() { } } - fun stop(context: Context) { - val intent = Intent(context, FetchPushForegroundService::class.java) - context.stopService(intent) + suspend fun stop(context: Context) = stopMutex.withLock { + val runningServiceInfo = getRunningServiceInfo(context) + if (runningServiceInfo != null) { + val intent = Intent(context, FetchPushForegroundService::class.java) + // If it's still not running in foreground, it means the service is still starting, + // so we delay the stop to give it time to start and be set as foreground, otherwise we can crash + // with `ForegroundServiceDidNotStartInTimeException`. + var isInForeground = runningServiceInfo.foreground + withTimeoutOrNull(5.seconds) { + while (!isInForeground) { + delay(50) + val updatedServiceInfo = getRunningServiceInfo(context) + if (updatedServiceInfo == null) { + Timber.d("FetchPushForegroundService is no longer running, no need to stop it.") + return@withTimeoutOrNull + } + isInForeground = updatedServiceInfo.foreground == true + } + } ?: Timber.w("FetchPushForegroundService did not start in foreground after 5s, stopping it anyway.") + context.stopService(intent) + } + } + + @Suppress("DEPRECATION") + private fun getRunningServiceInfo(context: Context): ActivityManager.RunningServiceInfo? { + val activityManager = context.getSystemService(ACTIVITY_SERVICE) as ActivityManager + return activityManager.getRunningServices(Int.MAX_VALUE) + .firstOrNull { it.service.className == FetchPushForegroundService::class.java.name } } } } diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/push/FakePushHandlingWakeLock.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/push/FakePushHandlingWakeLock.kt index 925581db9b..077c8f661e 100644 --- a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/push/FakePushHandlingWakeLock.kt +++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/push/FakePushHandlingWakeLock.kt @@ -18,7 +18,7 @@ class FakePushHandlingWakeLock( lock.invoke(time) } - override fun unlock() { + override suspend fun unlock() { unlock.invoke() } } From 183a89bff978174ba56a8111483061dbe8f540f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 08:11:54 +0100 Subject: [PATCH 087/103] fix(deps): update dependency io.element.android:emojibase-bindings to v1.5.1 (#6474) 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 a8ca47e959..68d381df85 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -226,7 +226,7 @@ sentry = "io.sentry:sentry-android:8.36.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.33.2" # Emojibase -matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.5.0" +matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.5.1" sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0" # Di From 44821e0e42305e7864b23022d622b9c022db36de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 08:13:05 +0100 Subject: [PATCH 088/103] fix(deps): update dependency com.google.firebase:firebase-bom to v34.11.0 (#6478) 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 68d381df85..f2f6d5afea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -80,7 +80,7 @@ kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin kover_gradle_plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" } ksp_gradle_plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } # https://firebase.google.com/docs/android/setup#available-libraries -google_firebase_bom = "com.google.firebase:firebase-bom:34.10.0" +google_firebase_bom = "com.google.firebase:firebase-bom:34.11.0" firebase_appdistribution_gradle = { module = "com.google.firebase:firebase-appdistribution-gradle", version.ref = "firebaseAppDistribution" } autonomousapps_dependencyanalysis_plugin = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysis" } ksp_plugin = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } From 69aeee67a561235f93111f7dd9cc4963b134f3ad Mon Sep 17 00:00:00 2001 From: bxdxnn <267911624+bxdxnn@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:26:16 +0300 Subject: [PATCH 089/103] Fix media cover placeholder floating (#6484) --- .../impl/local/audio/MediaAudioView.kt | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/audio/MediaAudioView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/audio/MediaAudioView.kt index 01115b7c91..cb9d6ae9c8 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/audio/MediaAudioView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/audio/MediaAudioView.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -51,6 +52,7 @@ import androidx.media3.common.Timeline import androidx.media3.exoplayer.ExoPlayer import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView +import com.bumble.appyx.core.node.LocalNodeTargetVisibility import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.audio.api.AudioFocus @@ -130,6 +132,8 @@ private fun ExoPlayerMediaAudioView( mutableStateOf(null) } + val isTargetVisible = LocalNodeTargetVisibility.current + val playableState: PlayableState.Playable by remember { derivedStateOf { PlayableState.Playable( @@ -196,13 +200,21 @@ private fun ExoPlayerMediaAudioView( exoPlayer.pause() } } + LaunchedEffect(isTargetVisible) { + if (!isTargetVisible) { + exoPlayer.pause() + } + } if (localMedia?.uri != null) { LaunchedEffect(localMedia.uri) { val mediaItem = MediaItem.fromUri(localMedia.uri) exoPlayer.setMediaItem(mediaItem) + exoPlayer.prepare() } } else { - exoPlayer.setMediaItems(emptyList()) + LaunchedEffect(Unit) { + exoPlayer.setMediaItems(emptyList()) + } } val context = LocalContext.current val waveform = info?.waveform @@ -247,7 +259,7 @@ private fun ExoPlayerMediaAudioView( } }, update = { playerView -> - playerView.isVisible = metadata.hasArtwork() + playerView.isVisible = metadata.hasArtwork() && isTargetVisible }, onRelease = { playerView -> playerView.player = null @@ -317,16 +329,19 @@ private fun ExoPlayerMediaAudioView( ) } - OnLifecycleEvent { _, event -> - when (event) { - Lifecycle.Event.ON_CREATE -> exoPlayer.addListener(playerListener) - Lifecycle.Event.ON_RESUME -> exoPlayer.prepare() - Lifecycle.Event.ON_PAUSE -> exoPlayer.pause() - Lifecycle.Event.ON_DESTROY -> { - exoPlayer.release() + DisposableEffect(exoPlayer) { + exoPlayer.addListener(playerListener) + onDispose { + if (!exoPlayer.isReleased) { exoPlayer.removeListener(playerListener) + exoPlayer.release() } - else -> Unit + } + } + + OnLifecycleEvent { _, event -> + if (event == Lifecycle.Event.ON_PAUSE) { + exoPlayer.pause() } } } From c89fc2b6b13033226bb0cbb3e77efc89c64a1f24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:22:33 +0200 Subject: [PATCH 090/103] fix(deps): update dependency io.element.android:emojibase-bindings to v1.5.2 (#6487) 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 f2f6d5afea..86db5a9d73 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -226,7 +226,7 @@ sentry = "io.sentry:sentry-android:8.36.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.33.2" # Emojibase -matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.5.1" +matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.5.2" sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0" # Di From 47251489193c42cb0c5aa9ec1e8f15075167102d Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 30 Mar 2026 18:44:08 +0200 Subject: [PATCH 091/103] Try handling `ForegroundServiceStartNotAllowedException` better (#6483) * Try handling `ForegroundServiceStartNotAllowedException` better The docs mention starting a foreground service when the app is on background is allowed when FCM receives a high priority notification, so we don't do it if the priority is not high. Also, we handle the case where starting the foreground service fails so it doesn't crash the app. --- .../impl/push/FetchPushForegroundService.kt | 38 ++++++++++++++++--- .../VectorFirebaseMessagingService.kt | 14 +++++-- .../VectorFirebaseMessagingServiceTest.kt | 29 ++++++++++++++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt index d7cc950b99..6dc6bdfa0e 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/FetchPushForegroundService.kt @@ -17,6 +17,7 @@ import android.os.PowerManager import androidx.core.app.NotificationCompat import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.bindings +import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.push.api.push.PushHandlingWakeLock @@ -57,6 +58,8 @@ class FetchPushForegroundService : Service() { } } + private var isOnForeground = false + override fun onCreate() { Timber.d("Creating FetchPushForegroundService") @@ -71,12 +74,32 @@ class FetchPushForegroundService : Service() { .setVibrate(longArrayOf(0)) .setSound(null) .build() - startForeground(NOTIFICATION_ID, notificationCompat) + + // Try to start the service in foreground. This can fail, even in cases where it's supposed to work according to the docs. + // In those cases we catch the exception and handle the failure so we don't try to start the wakelock or stop the service + // from running in foreground later. + runCatchingExceptions { + startForeground(NOTIFICATION_ID, notificationCompat) + } + .onSuccess { + isOnForeground = true + Timber.d("FetchPushForegroundService started in foreground successfully") + } + .onFailure { + isOnForeground = false + Timber.e(it, "Failed to start FetchPushForegroundService in foreground") + } super.onCreate() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (!isOnForeground) { + Timber.w("FetchPushForegroundService is not running in foreground, stopping it to avoid crash") + stopSelf() + return START_NOT_STICKY + } + wakelock.acquire(wakelockTimeout) // The timeout is not automatic before Android 15, so we need to schedule it ourselves @@ -91,18 +114,21 @@ class FetchPushForegroundService : Service() { } override fun stopService(intent: Intent?): Boolean { - wakelock.release() + if (isOnForeground) { + wakelock.release() + stopForeground(STOP_FOREGROUND_REMOVE) + } - stopForeground(STOP_FOREGROUND_REMOVE) return super.stopService(intent) } override fun onTimeout(startId: Int) { super.onTimeout(startId) - Timber.d("Wakelock timeout reached, stopping FetchPushForegroundService") - - coroutineScope.launch { pushHandlingWakeLock.unlock() } + if (isOnForeground) { + Timber.d("Wakelock timeout reached, stopping FetchPushForegroundService") + coroutineScope.launch { pushHandlingWakeLock.unlock() } + } } companion object { diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingService.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingService.kt index 67da09f1ab..3961f1f591 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingService.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingService.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.pushproviders.firebase import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage +import com.google.firebase.messaging.RemoteMessage.PRIORITY_HIGH import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.bindings import io.element.android.libraries.core.log.logger.LoggerTag @@ -45,8 +46,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { Timber.tag(loggerTag.value).w("New Firebase message. Priority: ${message.priority}/${message.originalPriority}") - // Acquire wakelock to ensure the device stays awake while we handle the push and schedule and run the work - pushHandlingWakeLock.lock() + val isHighPriority = message.priority == PRIORITY_HIGH + if (isHighPriority) { + // Acquire wakelock to ensure the device stays awake while we handle the push and schedule and run the work + pushHandlingWakeLock.lock() + } coroutineScope.launch { val pushData = pushParser.parse(message.data) @@ -58,7 +62,9 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { "$it: ${message.data[it]}" }, ) - pushHandlingWakeLock.unlock() + if (isHighPriority) { + pushHandlingWakeLock.unlock() + } } else { val handled = pushHandler.handle( pushData = pushData, @@ -66,7 +72,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { ) // If we failed to handle the push, we should release the wakelock early to avoid keeping the device awake for too long. - if (!handled) { + if (!handled && isHighPriority) { pushHandlingWakeLock.unlock() } } diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt index 87ca74730c..798328e626 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt @@ -96,6 +96,7 @@ class VectorFirebaseMessagingServiceTest { putString("event_id", AN_EVENT_ID.value) putString("room_id", A_ROOM_ID.value) putString("cs", A_SECRET) + putString("google.priority", "high") }, ) ) @@ -127,6 +128,7 @@ class VectorFirebaseMessagingServiceTest { putString("event_id", AN_EVENT_ID.value) putString("room_id", A_ROOM_ID.value) putString("cs", A_SECRET) + putString("google.priority", "high") }, ) ) @@ -141,6 +143,33 @@ class VectorFirebaseMessagingServiceTest { unlockLambda.assertions().isCalledOnce() } + @Test + fun `test pushHandler with a remote message with normal priority won't lock the wakelock`() = runTest { + val lockLambda = lambdaRecorder { _ -> } + val unlockLambda = lambdaRecorder { } + val vectorFirebaseMessagingService = createVectorFirebaseMessagingService( + pushHandler = FakePushHandler(handleResult = { _, _ -> false }), + pushHandlingWakeLock = FakePushHandlingWakeLock( + lock = lockLambda, + unlock = unlockLambda + ) + ) + vectorFirebaseMessagingService.onMessageReceived( + message = RemoteMessage( + Bundle().apply { + putString("event_id", AN_EVENT_ID.value) + putString("room_id", A_ROOM_ID.value) + putString("cs", A_SECRET) + putString("google.priority", "normal") + }, + ) + ) + + // The wakelock should not be locked + lockLambda.assertions().isNeverCalled() + unlockLambda.assertions().isNeverCalled() + } + @Test fun `test new token is forwarded to the handler`() = runTest { val lambda = lambdaRecorder { } From 01dd79fa93d4fa2b6f5b63bf997becad8c84b6f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 10:57:48 +0000 Subject: [PATCH 092/103] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.31 --- 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 86db5a9d73..e0d4119abc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -178,7 +178,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:26.03.24" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.03.31" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From 4c15d9cad186fef1a4b84dba04ed18c711995062 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 31 Mar 2026 15:47:21 +0200 Subject: [PATCH 093/103] Fix permissions to publish GitHub pages. --- .github/workflows/generate_github_pages.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/generate_github_pages.yml b/.github/workflows/generate_github_pages.yml index e4fedf76ac..5006cc44b5 100644 --- a/.github/workflows/generate_github_pages.yml +++ b/.github/workflows/generate_github_pages.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-latest # Skip in forks if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} + permissions: + contents: write steps: - name: ā¬ Checkout with LFS uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4 From f4986d4a0b946104dbb32f7674354387ea65725d Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:48:37 +0200 Subject: [PATCH 094/103] Sync Strings from Localazy (#6486) Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com> --- .../src/main/res/values-da/translations.xml | 4 +- .../src/main/res/values-da/translations.xml | 6 +- .../src/main/res/values-da/translations.xml | 4 + .../src/main/res/values-da/translations.xml | 4 +- .../src/main/res/values-da/translations.xml | 25 +- .../src/main/res/values-da/translations.xml | 27 +- .../src/main/res/values-ru/translations.xml | 3 +- .../src/main/res/values-da/translations.xml | 10 +- .../src/main/res/values-da/translations.xml | 36 +- .../src/main/res/values-ru/translations.xml | 3 + .../src/main/res/values/localazy.xml | 1 + ...nfigureroom_ConfigureRoomViewDark_0_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_1_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_2_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_3_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_4_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_5_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_6_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_7_de.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_8_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_0_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_1_de.png | 2 +- ...figureroom_ConfigureRoomViewLight_2_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_3_de.png | 2 +- ...figureroom_ConfigureRoomViewLight_4_de.png | 2 +- ...figureroom_ConfigureRoomViewLight_5_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_6_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_7_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_8_de.png | 4 +- ...me.impl.spaces_HomeSpacesView_Day_0_de.png | 4 +- ...me.impl.spaces_HomeSpacesView_Day_1_de.png | 4 +- ...me.impl.spaces_HomeSpacesView_Day_2_de.png | 4 +- .../features.home.impl_HomeView_Day_4_de.png | 4 +- ...es.joinroom.impl_JoinRoomView_Day_9_de.png | 4 +- ...on.impl.send_SendLocationView_Day_0_de.png | 3 - ...on.impl.send_SendLocationView_Day_1_de.png | 3 - ...on.impl.send_SendLocationView_Day_2_de.png | 3 - ...on.impl.send_SendLocationView_Day_3_de.png | 3 - ...on.impl.send_SendLocationView_Day_4_de.png | 3 - ....impl.share_ShareLocationView_Day_0_de.png | 3 + ....impl.share_ShareLocationView_Day_1_de.png | 3 + ....impl.share_ShareLocationView_Day_2_de.png | 3 + ....impl.share_ShareLocationView_Day_3_de.png | 3 + ....impl.share_ShareLocationView_Day_4_de.png | 3 + ....impl.share_ShareLocationView_Day_5_de.png | 3 + ....impl.share_ShareLocationView_Day_6_de.png | 3 + ...on.impl.show_ShowLocationView_Day_0_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_1_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_2_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_3_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_4_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_5_de.png | 4 +- ...on.impl.show_ShowLocationView_Day_6_de.png | 3 - ...on.impl.show_ShowLocationView_Day_7_de.png | 3 - ...essagesViewWithIdentityChange_Day_0_de.png | 4 +- ...essagesViewWithIdentityChange_Day_1_de.png | 4 +- ...ecomposer_MessageComposerView_Day_0_de.png | 4 +- ...d.list_PinnedMessagesListView_Day_3_de.png | 4 +- ...mEventRowWithReplyInformative_Day_0_de.png | 4 +- ...mEventRowWithReplyInformative_Day_1_de.png | 4 +- ...TimelineItemEventRowWithReply_Day_4_de.png | 4 +- ...TimelineItemEventRowWithReply_Day_8_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_10_de.png | 3 + ...s.impl.timeline_TimelineView_Day_11_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_12_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_13_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_14_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_15_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_16_de.png | 4 +- ...s.impl.timeline_TimelineView_Day_17_de.png | 3 - ...es.impl.timeline_TimelineView_Day_4_de.png | 4 +- ...es.impl.timeline_TimelineView_Day_6_de.png | 4 +- ...s.messages.impl_MessagesView_Day_10_de.png | 4 +- ...itprofile_EditUserProfileView_Day_0_de.png | 4 +- ...itprofile_EditUserProfileView_Day_1_de.png | 4 +- ...itprofile_EditUserProfileView_Day_2_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_0_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_10_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_11_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_12_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_13_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_14_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_15_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_16_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_17_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_18_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_19_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_1_de.png | 2 +- ...roomdetails.impl_RoomDetailsDark_20_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_21_de.png | 4 +- ...roomdetails.impl_RoomDetailsDark_22_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_2_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_3_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_4_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_5_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_6_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_7_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_8_de.png | 4 +- ....roomdetails.impl_RoomDetailsDark_9_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_0_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_10_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_11_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_12_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_13_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_14_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_15_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_16_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_17_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_18_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_19_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_1_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_20_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_21_de.png | 4 +- ...res.roomdetails.impl_RoomDetails_22_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_2_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_3_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_4_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_5_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_6_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_7_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_8_de.png | 4 +- ...ures.roomdetails.impl_RoomDetails_9_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_0_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_1_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_2_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_3_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_4_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_5_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_6_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_7_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_8_de.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_9_de.png | 4 +- ...pl.root_SecureBackupRootView_Day_14_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_0_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_1_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_2_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_3_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_4_de.png | 4 +- ...res.space.impl.root_SpaceView_Day_5_de.png | 4 +- ...ared_UserProfileHeaderSection_Day_0_de.png | 4 +- ...rofile.shared_UserProfileView_Day_2_de.png | 4 +- ...mePickerHorizontal_DateTime_pickers_de.png | 4 +- ...PickerVerticalDark_DateTime_pickers_de.png | 4 +- ...ickerVerticalLight_DateTime_pickers_de.png | 4 +- ...components_OrganizationHeader_Day_0_de.png | 4 +- ...omponents_SpaceHeaderRootView_Day_0_de.png | 4 +- ...ix.ui.components_SpaceInfoRow_Day_0_de.png | 4 +- ....messages.reply_InReplyToView_Day_4_de.png | 4 +- ....messages.reply_InReplyToView_Day_8_de.png | 4 +- ...oser_MarkdownTextComposerEdit_Day_0_de.png | 4 +- ...mposer_TextComposerAddCaption_Day_0_de.png | 4 +- ...poser_TextComposerEditCaption_Day_0_de.png | 4 +- ..._TextComposerEditNotEncrypted_Day_0_de.png | 4 +- ...textcomposer_TextComposerEdit_Day_0_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_0_de.png | 4 +- ...extComposerReplyNotEncrypted_Day_10_de.png | 4 +- ...extComposerReplyNotEncrypted_Day_11_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_1_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_2_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_3_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_4_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_5_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_6_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_7_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_8_de.png | 4 +- ...TextComposerReplyNotEncrypted_Day_9_de.png | 4 +- ...extcomposer_TextComposerReply_Day_0_de.png | 4 +- ...xtcomposer_TextComposerReply_Day_10_de.png | 4 +- ...xtcomposer_TextComposerReply_Day_11_de.png | 4 +- ...extcomposer_TextComposerReply_Day_1_de.png | 4 +- ...extcomposer_TextComposerReply_Day_2_de.png | 4 +- ...extcomposer_TextComposerReply_Day_3_de.png | 4 +- ...extcomposer_TextComposerReply_Day_4_de.png | 4 +- ...extcomposer_TextComposerReply_Day_5_de.png | 4 +- ...extcomposer_TextComposerReply_Day_6_de.png | 4 +- ...extcomposer_TextComposerReply_Day_7_de.png | 4 +- ...extcomposer_TextComposerReply_Day_8_de.png | 4 +- ...extcomposer_TextComposerReply_Day_9_de.png | 4 +- ...extComposerSimpleNotEncrypted_Day_0_de.png | 4 +- ...xtcomposer_TextComposerSimple_Day_0_de.png | 4 +- screenshots/html/data.js | 2034 +++++++++-------- ...system.components_LocationPin_Day_0_en.png | 4 +- 182 files changed, 1418 insertions(+), 1395 deletions(-) create mode 100644 features/location/impl/src/main/res/values-da/translations.xml delete mode 100644 screenshots/de/features.location.impl.send_SendLocationView_Day_0_de.png delete mode 100644 screenshots/de/features.location.impl.send_SendLocationView_Day_1_de.png delete mode 100644 screenshots/de/features.location.impl.send_SendLocationView_Day_2_de.png delete mode 100644 screenshots/de/features.location.impl.send_SendLocationView_Day_3_de.png delete mode 100644 screenshots/de/features.location.impl.send_SendLocationView_Day_4_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_0_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_1_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_2_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_3_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_4_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_5_de.png create mode 100644 screenshots/de/features.location.impl.share_ShareLocationView_Day_6_de.png delete mode 100644 screenshots/de/features.location.impl.show_ShowLocationView_Day_6_de.png delete mode 100644 screenshots/de/features.location.impl.show_ShowLocationView_Day_7_de.png create mode 100644 screenshots/de/features.messages.impl.timeline_TimelineView_Day_10_de.png delete mode 100644 screenshots/de/features.messages.impl.timeline_TimelineView_Day_17_de.png diff --git a/features/ftue/impl/src/main/res/values-da/translations.xml b/features/ftue/impl/src/main/res/values-da/translations.xml index 9c3720ac00..473c8a9c73 100644 --- a/features/ftue/impl/src/main/res/values-da/translations.xml +++ b/features/ftue/impl/src/main/res/values-da/translations.xml @@ -2,8 +2,8 @@ "Kan ikke bekrƦfte?" "Opret en ny gendannelsesnĆøgle" - "VerificĆ©r denne enhed for at konfigurere sikre meddelelser." - "BekrƦft din identitet" + "VƦlg, hvordan du vil verificere dig for at konfigurere sikre beskeder." + "BekrƦft din digitale identitet" "Brug en anden enhed" "Brug gendannelsesnĆøgle" "Nu kan du lƦse eller sende beskeder sikkert, og enhver du samtaler med kan ogsĆ„ stole pĆ„ denne enhed." 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 cd9ec06ada..fab528ce71 100644 --- a/features/home/impl/src/main/res/values-da/translations.xml +++ b/features/home/impl/src/main/res/values-da/translations.xml @@ -5,9 +5,9 @@ "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" + "Dine chats sikkerhedskopieres automatisk med end-to-end-kryptering. For at kunne gendanne denne sikkerhedskopi og bevare din digitale identitet, hvis du mister adgang til alle dine enheder, fĆ„r du brug for din gendannelsesnĆøgle." + "Hent gendannelsesnĆøgle" + "Sikkerhedskopier dine samtaler" "BekrƦft din gendannelsesnĆøgle for at bevare adgangen til nĆøglelager og meddelelseshistorik." "Indtast din gendannelsesnĆøgle" "Har du glemt din gendannelsesnĆøgle?" diff --git a/features/location/impl/src/main/res/values-da/translations.xml b/features/location/impl/src/main/res/values-da/translations.xml new file mode 100644 index 0000000000..f15ab0fb2f --- /dev/null +++ b/features/location/impl/src/main/res/values-da/translations.xml @@ -0,0 +1,4 @@ + + + "VƦlg, hvor lƦnge du vil dele din aktuelle position." + diff --git a/features/lockscreen/impl/src/main/res/values-da/translations.xml b/features/lockscreen/impl/src/main/res/values-da/translations.xml index ffbd657970..76725ac637 100644 --- a/features/lockscreen/impl/src/main/res/values-da/translations.xml +++ b/features/lockscreen/impl/src/main/res/values-da/translations.xml @@ -23,7 +23,7 @@ VƦlg noget mindevƦrdigt. Hvis du glemmer denne pinkode, bliver du logget ud af "Indtast venligst den samme PIN-kode to gange" "PIN-koderne stemmer ikke overens" "Du vil vƦre nĆødt til at logge ind igen og oprette en ny PIN-kode for at fortsƦtte." - "Du bliver logget ud" + "Denne enhed bliver fjernet" "Du har %1$d forsĆøg pĆ„ at lĆ„se op" "Du har %1$d forsĆøg pĆ„ at lĆ„se op" @@ -34,5 +34,5 @@ VƦlg noget mindevƦrdigt. Hvis du glemmer denne pinkode, bliver du logget ud af "Brug biometri" "Brug PIN-kode" - "Logger ud…" + "Fjerner enhed…" diff --git a/features/logout/impl/src/main/res/values-da/translations.xml b/features/logout/impl/src/main/res/values-da/translations.xml index a828cd48b8..6bf98f8db5 100644 --- a/features/logout/impl/src/main/res/values-da/translations.xml +++ b/features/logout/impl/src/main/res/values-da/translations.xml @@ -1,17 +1,18 @@ - "Er du sikker pĆ„, at du vil logge ud?" - "Log ud" - "Log ud" - "Logger ud…" - "Du er ved at logge ud af din sidste session. Hvis du logger ud nu, mister du adgangen til dine krypterede meddelelser." - "Du har slĆ„et sikkerhedskopiering fra" - "Dine nĆøgler blev stadig sikkerhedskopieret, da du gik offline. Opret forbindelse igen, sĆ„ dine nĆøgler kan sikkerhedskopieres, fĆør du logger ud." + "Er du sikker pĆ„, at Ćønsker at fjerne denne enhed?" + "Fjern denne enhed" + "Fjern denne enhed" + "Fjerner enhed…" + "Dette er din eneste enhed. Hvis du fjerner den, skal du bruge en gendannelsesnĆøgle for at bekrƦfte din digitale identitet og gendanne dine krypterede chats, nƦste gang du logger ind." + "Du er ved at miste adgangen til dine krypterede chats" + "Dine nĆøgler blev stadig sikkerhedskopieret, da du gik offline. Opret forbindelse igen, sĆ„ dine nĆøgler kan sikkerhedskopieres, fĆør du fjerner denne enhed." "Dine nĆøgler bliver stadig sikkerhedskopieret" - "Vent pĆ„, at dette er fuldfĆørt, fĆør du logger ud." + "Vent venligst, indtil dette er fƦrdigt, fĆør du fjerner denne enhed." "Dine nĆøgler bliver stadig sikkerhedskopieret" - "Log ud" - "Du er ved at logge ud af din sidste session. Hvis du logger af nu, mister du adgangen til dine krypterede meddelelser." - "Gendannelse er ikke konfigureret" - "Du er ved at logge ud af din sidste session. Hvis du logger af nu, kan du miste adgangen til dine krypterede meddelelser." + "Fjern denne enhed" + "Dette er din eneste enhed. Hvis du fjerner den, skal du bruge en gendannelsesnĆøgle for at bekrƦfte din digitale identitet og gendanne dine krypterede chats, nƦste gang du logger ind." + "Du er ved at miste adgangen til dine krypterede chats" + "Dette er din eneste enhed. Hvis du fjerner den, skal du bruge en gendannelsesnĆøgle for at bekrƦfte din digitale identitet og gendanne dine krypterede chats, nƦste gang du logger ind." + "SĆørg for, at du har adgang til din gendannelsesnĆøgle, fĆør du fjerner denne enhed." diff --git a/features/securebackup/impl/src/main/res/values-da/translations.xml b/features/securebackup/impl/src/main/res/values-da/translations.xml index 93b949bfb6..941b7fc480 100644 --- a/features/securebackup/impl/src/main/res/values-da/translations.xml +++ b/features/securebackup/impl/src/main/res/values-da/translations.xml @@ -2,16 +2,17 @@ "Slet nĆøglelager" "AktivĆ©r sikkerhedskopiering" - "Gem din kryptografiske identitet og meddelelsesnĆøgler sikkert pĆ„ serveren. Dette giver dig mulighed for at se din meddelelseshistorik pĆ„ alle nye enheder. %1$s." + "Dette giver dig mulighed for at se din chathistorik pĆ„ alle nye enheder og er pĆ„krƦvet til sikkerhedskopiering af chats og digital identitet.%1$s ." "NĆøgleopbevaring" - "NĆøglelagring skal vƦre slĆ„et til for at konfigurere gendannelse." + "NĆøglelagring skal vƦre slĆ„et til for at konfigurere gendannelse af dine samtaler." "Upload nĆøgler fra denne enhed" "Tillad lagring af nĆøgler" "Skift gendannelsesnĆøgle" - "Gendan din kryptografiske identitet og beskedhistorik med en gendannelsesnĆøgle, hvis du har mistet alle dine eksisterende enheder." + "Dine samtaler sikkerhedskopieres automatisk med end-to-end-kryptering. For at kunne gendanne denne sikkerhedskopi og bevare din digitale identitet, hvis du mister adgang til alle dine enheder, fĆ„r du brug for din gendannelsesnĆøgle." "Indtast gendannelsesnĆøgle" "Din nĆøglelagring er i Ćøjeblikket ikke synkroniseret." - "OpsƦt gendannelse" + "Hent gendannelsesnĆøgle" + "Dine chats sikkerhedskopieres automatisk med end-to-end-kryptering. For at kunne gendanne denne sikkerhedskopi og bevare din digitale identitet, hvis du mister adgang til alle dine enheder, fĆ„r du brug for din gendannelsesnĆøgle." "ƅbn %1$s pĆ„ en stationƦr enhed" "Log ind pĆ„ din konto igen" "NĆ„r du bliver bedt om at verificere din enhed, skal du vƦlge %1$s" @@ -23,12 +24,12 @@ "Dine kontodetaljer, kontakter, personlige indstilliger og samtaler vil blive gemt" "Du mister al beskedhistorik, der kun er gemt pĆ„ serveren." "Du bliver nĆødt til at verificere alle dine eksisterende enheder og kontakter pĆ„ny" - "Nulstil kun din identitet, hvis du ikke har adgang til en anden enhed, der er logget ind, og du har mistet din gendannelsesnĆøgle." - "Kan du ikke bekrƦfte? Du skal nulstille din identitet." - "SlĆ„ fra" - "Du mister dine krypterede meddelelser, hvis du er logget ud af alle enheder." - "Er du sikker pĆ„, at du vil slĆ„ sikkerhedskopiering fra?" - "Hvis du sletter nĆøglelageret, fjernes din kryptografiske identitet og meddelelsesnĆøgler fra serveren og fĆølgende sikkerhedsfunktioner deaktiveres:" + "Nulstil kun din digitale identitet, hvis du ikke har adgang til en anden enhed, der er logget ind, og du har mistet din gendannelsesnĆøgle." + "Kan du ikke bekrƦfte? Du er nĆødt til at nulstille din digitale identitet." + "Slet" + "Du mister din krypterede chathistorik og skal nulstille din digitale identitet, hvis du fjerner alle dine enheder." + "Er du sikker pĆ„, at du vil slette nĆøglelageret?" + "Hvis du sletter nĆøglelageret, fjernes din kryptografiske identitet og beskednĆøgler fra serveren og fĆølgende sikkerhedsfunktioner deaktiveres:" "Du vil ikke kunne se historikken for krypterede beskeder pĆ„ nye enheder" "Du mister adgangen til dine krypterede meddelelser, hvis du er logget ud %1$s overalt" "Er du sikker pĆ„, at du vil deaktivere nĆøglelagring og slette lageret?" @@ -58,12 +59,12 @@ "Generer din gendannelsesnĆøgle" "Del ikke dette med nogen!" "OpsƦtning af gendannelse lykkedes" - "OpsƦt gendannelse" + "Hent gendannelsesnĆøgle" "Ja, nulstil nu" "Denne proces er irreversibel." - "Er du sikker pĆ„, at du Ćønsker at nulstille din identitet?" + "Er du sikker pĆ„, at du vil nulstille din digitale identitet?" "Der opstod en ukendt fejl. Kontroller, at adgangskoden til din konto er korrekt, og prĆøv igen." "Indtast…" - "BekrƦft, at du Ćønsker at nulstille din identitet." + "BekrƦft, at du Ćønsker at nulstille din digitale identitet." "Indtast adgangskoden til din konto for at fortsƦtte" diff --git a/features/securebackup/impl/src/main/res/values-ru/translations.xml b/features/securebackup/impl/src/main/res/values-ru/translations.xml index 4ae9a2e423..35da59cdb9 100644 --- a/features/securebackup/impl/src/main/res/values-ru/translations.xml +++ b/features/securebackup/impl/src/main/res/values-ru/translations.xml @@ -12,6 +12,7 @@ "ВвеГите ŠŗŠ»ŃŽŃ‡ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŃ" "Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń Ń€ŠµŠ·ŠµŃ€Š²Š½Š°Ń ŠŗŠ¾ŠæŠøŃ Š²Š°ŃˆŠøŃ… чатов не синхронизирована." "ŠŸŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ŠŗŠ»ŃŽŃ‡ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŃ" + "Š’Š°ŃˆŠø чаты автоматически Ń€ŠµŠ·ŠµŃ€Š²ŠøŃ€ŃƒŃŽŃ‚ŃŃ с использованием сквозного ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŃ. Š”Š»Ń Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŃ ŃŃ‚Š¾Š¹ резервной копии Šø ŃŠ¾Ń…Ń€Š°Š½ŠµŠ½ŠøŃ вашей цифровой личности в ŃŠ»ŃƒŃ‡Š°Šµ потери Š“Š¾ŃŃ‚ŃƒŠæŠ° ко всем вашим ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Š¼ вам ŠæŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ ŠŗŠ»ŃŽŃ‡ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŃ." "ŠžŃ‚ŠŗŃ€Š¾Š¹Ń‚Šµ %1$s на ŠŗŠ¾Š¼ŠæŃŒŃŽŃ‚ере" "ВойГите в свой Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚ еще раз" "КогГа ŠæŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ ŠæŠ¾Š“Ń‚Š²ŠµŃ€Š“ŠøŃ‚ŃŒ ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾, выберите %1$s" @@ -25,7 +26,7 @@ "Вам нужно Š±ŃƒŠ“ет заново ŠæŠ¾Š“Ń‚Š²ŠµŃ€Š“ŠøŃ‚ŃŒ все ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŃŽŃ‰ŠøŠµ ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š° Šø контакты." "Дбрасывайте Š»ŠøŃ‡Š½Š¾ŃŃ‚ŃŒ Ń‚Š¾Š»ŃŒŠŗŠ¾ в том ŃŠ»ŃƒŃ‡Š°Šµ, если у вас нет Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ Š“Ń€ŃƒŠ³ŠøŠ¼ ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Ńƒ, на которых выполнен вхоГ, Šø вы ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø ŠŗŠ»ŃŽŃ‡ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŃ." "ŠŠµ можете ŠæŠ¾Š“Ń‚Š²ŠµŃ€Š“ŠøŃ‚ŃŒ? Вам ŠæŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ ŃŠ±Ń€Š¾ŃŠøŃ‚ŃŒ Š»ŠøŃ‡Š½Š¾ŃŃ‚ŃŒ вашей ŃƒŃ‡ŠµŃ‚Š½Š¾Š¹ записи." - "Š’Ń‹ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ" + "Š£Š“Š°Š»ŠøŃ‚ŃŒ" "Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠµŃ‚Šµ Š·Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Š½Ń‹Šµ ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃ, если выйГете ŠøŠ· всех ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²." "Š’Ń‹ Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ хотите Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ резервное копирование?" "УГаление хранилища ŠŗŠ»ŃŽŃ‡ŠµŠ¹ привеГёт Šŗ ŃƒŠ“Š°Š»ŠµŠ½ŠøŃŽ вашей криптографической личности Šø ŠŗŠ»ŃŽŃ‡ŠµŠ¹ сообщений с сервера, а также Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŃŽ ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŃ… Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹ безопасности:" diff --git a/features/verifysession/impl/src/main/res/values-da/translations.xml b/features/verifysession/impl/src/main/res/values-da/translations.xml index 32cdf159d5..90e227eae6 100644 --- a/features/verifysession/impl/src/main/res/values-da/translations.xml +++ b/features/verifysession/impl/src/main/res/values-da/translations.xml @@ -2,8 +2,8 @@ "Kan ikke bekrƦfte?" "Opret en ny gendannelsesnĆøgle" - "VerificĆ©r denne enhed for at konfigurere sikre meddelelser." - "BekrƦft din identitet" + "VƦlg, hvordan du vil verificere dig for at konfigurere sikre beskeder." + "BekrƦft din digitale identitet" "Brug en anden enhed" "Brug gendannelsesnĆøgle" "Nu kan du lƦse eller sende beskeder sikkert, og enhver du samtaler med kan ogsĆ„ stole pĆ„ denne enhed." @@ -17,7 +17,7 @@ "BekrƦft, at numrene nedenfor stemmer overens med dem, der vises pĆ„ din anden session." "Sammenlign tal" "Nu kan du lƦse eller sende beskeder sikkert med din anden enhed." - "Nu kan du stole pĆ„ identiteten af denne bruger, nĆ„r I sender og modtager beskeder fra hinanden." + "Nu kan du stole pĆ„ denne brugers digitale identitet, nĆ„r I sender eller modtager beskeder." "Enhed verificeret" "Indtast gendannelsesnĆøgle" "Enten udlĆøb anmodningen, den blev afvist, eller der var en fejl i verifikationen." @@ -42,7 +42,7 @@ "ƅbn appen pĆ„ en anden bekrƦftet enhed" "For ekstra sikkerhed, verificĆ©r denne bruger ved at sammenligne et sƦt emojier pĆ„ jeres enheder. GĆør dette ved at bruge en kommunikationsmetode i stoler pĆ„." "VerificĆ©r denne bruger?" - "For ekstra sikkerhed Ćønsker en anden bruger at bekrƦfte din identitet. Du fĆ„r vist et sƦt emojier til sammenligning." + "For ekstra sikkerhed Ćønsker en anden bruger at bekrƦfte din digitale identitet. I vil blive vist et sƦt emojis, der skal sammenlignes." "Du burde se en popup pĆ„ den anden enhed. Start verifikationen derfra nu." "Start verifikation pĆ„ den anden enhed" "Start verifikation pĆ„ den anden enhed" @@ -50,5 +50,5 @@ "NĆ„r du er blevet accepteret, kan du fortsƦtte med verifikationen." "Accepter anmodningen om at starte bekrƦftelsesprocessen i din anden session for at fortsƦtte." "Venter pĆ„ at acceptere anmodningen" - "Logger ud…" + "Fjerner enhed…" 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 5d1a08a727..e12e049469 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -120,6 +120,7 @@ "Forlad klynge" "IndlƦs mere" "Administrer konto" + "Administrer konto og enheder" "Administrer enheder" "Administrer rum" "Besked" @@ -162,14 +163,15 @@ "Del liveplacering" "Vis" "Log ind igen" - "Log ud" - "Log ud alligevel" + "Fjern denne enhed" + "Fjern denne enhed alligevel" "Spring over" "Start" "Start samtale" "Begynd forfra" "Begynd verifikation" "Tryk for at indlƦse kort" + "Stop" "Tag billede" "Tryk for indstillinger" "OversƦt" @@ -190,6 +192,7 @@ "Avancerede indstillinger" "et billede" "Analyse-vƦrktĆøj" + "Synkroniserer notifikationer…" "Du forlod rummet" "Du blev logget ud af sessionen" "Udseende" @@ -223,6 +226,7 @@ "Tom fil" "Kryptering" "Kryptering aktiveret" + "Slutter kl.%1$s" "Indtast din PIN-kode" "Fejl" "Der opstod en fejl, du modtager muligvis ikke meddelelser om nye meddelelser. Fejlfinding af meddelelser fra indstillingerne. @@ -249,6 +253,8 @@ "Linje kopieret til udklipsholder" "Linket er kopieret til udklipsholderen" "Forbind ny enhed" + "Aktuel position" + "Aktuel position afsluttet" "IndlƦser…" "IndlƦser flere…" @@ -344,9 +350,10 @@ "Indstillinger" "Del klynge" "Nye medlemmer ser historik" + "Deling af aktuel position" "Delt placering" "Delt klynge" - "Logger ud" + "Fjerner enhed" "Noget gik galt" "Vi stĆødte pĆ„ et problem. PrĆøv venligst igen." "Klynge" @@ -366,12 +373,13 @@ "Tekst" "Tredjepartsmeddelelser" "TrĆ„d" + "TrĆ„de" "Emne" "Hvad handler det her rum om?" "Ude af stand til at dekryptere" "Sendt fra en usikker enhed" "Du har ikke adgang til denne meddelelse" - "Afsenderens verificerede identitet blev nulstillet" + "Afsenderens verificerede digitale identitet blev nulstillet" "Invitationer kunne ikke sendes til en eller flere brugere." "Kan ikke sende invitation(er)" "LĆ„s op" @@ -396,16 +404,17 @@ "Talebesked" "Venter…" "Venter pĆ„ denne besked" + "Venter pĆ„ aktuel position…" "Alle kan se historikken" "Dig" "%1$s(%2$s ) har delt denne besked siden du ikke var i rummet da den blev sendt." "%1$s delte denne besked, siden du ikke var i rummet da den blev sendt." "Dette rum er konfigureret, sĆ„ nye medlemmer kan lƦse historikken.%1$s" - "%1$ss identitet blev nulstillet. %2$s" - "%1$ss %2$s identitet blev nulstillet. %3$s" + "%1$ss digitale identitet blev nulstillet. %2$s" + "%1$ss %2$s digitale identitet blev nulstillet. %3$s" "(%1$s)" - "%1$ss identitet blev nulstillet." - "%1$ss %2$s identitet blev nulstillet. %3$s" + "%1$ss digitale identitet blev nulstillet." + "%1$ss %2$s digitale identitet blev nulstillet. %3$s" "TilbagetrƦk verifikation" "Tillad adgang" "Linket %1$s fĆører dig til et andet websted %2$s @@ -437,6 +446,7 @@ Er du sikker pĆ„, at du vil fortsƦtte?" "%1$s kunne ikke fĆ„ adgang til din placering. PrĆøv igen senere." "Kunne ikke uploade din talebesked." "Rummet findes ikke lƦngere, eller invitationen er ikke lƦngere gyldig." + "Aktiver venligst din GPS for at fĆ„ adgang til lokationsbaserede funktioner." "Meddelelsen blev ikke fundet" "%1$s har ikke tilladelse til at fĆ„ adgang til din placering. Du kan aktivere adgang i Indstillinger." "%1$s har ikke tilladelse til at se din placering. AktivĆ©r adgang nedenfor." @@ -464,11 +474,11 @@ Er du sikker pĆ„, at du vil fortsƦtte?" "%1$d Fastgjorte beskeder" "Fastgjorte beskeder" - "Du er ved at gĆ„ til din %1$s konto for at nulstille din identitet. Derefter vil du blive fĆørt tilbage til appen." - "Kan du ikke bekrƦfte? GĆ„ til din konto for at nulstille din identitet." + "Du er ved at gĆ„ til din %1$s konto for at nulstille din digitale identitet. Derefter vil du blive fĆørt tilbage til appen." + "Kan du ikke bekrƦfte? GĆ„ til din konto for at nulstille din digitale identitet." "TrƦk verifikationen tilbage og send" "Du kan trƦkke din verifikation tilbage og sende denne meddelelse alligevel, eller du kan annullere for nu og prĆøve igen senere efter at have gen-verificeret. %1$s" - "Din besked blev ikke sendt, fordi %1$s\'s verificerede identitet er blevet nulstillet" + "Din besked blev ikke sendt, fordi %1$s\'s verificerede digitale identitet er blevet nulstillet" "Send besked alligevel" "%1$s bruger en eller flere uverificerede enheder. Du kan sende beskeden alligevel, eller du kan annullere for nu og prĆøve igen senere, nĆ„r %2$s har bekrƦftet alle deres enheder." "Din besked blev ikke sendt, fordi %1$s ikke har bekrƦftet alle enheder" @@ -500,7 +510,7 @@ Er du sikker pĆ„, at du vil fortsƦtte?" "Klynger" "Delt %1$s" "PĆ„ kortet" - "Beskeden blev ikke sendt fordi %1$s s bekrƦftede identitet blev nulstillet." + "Beskeden blev ikke sendt fordi %1$s s bekrƦftede digitale identitet blev nulstillet." "Meddelelsen er ikke sendt, fordi %1$s ikke har bekrƦftet alle enheder." "Beskeden er ikke sendt, fordi du ikke har verificeret en eller flere af dine enheder." "Lokation" @@ -510,5 +520,5 @@ Er du sikker pĆ„, at du vil fortsƦtte?" "Du skal verificere denne enhed for at fĆ„ adgang til historiske beskeder" "Du har ikke adgang til denne meddelelse" "Kan ikke dekryptere beskeden" - "Denne besked blev blokeret, enten fordi du ikke verificerede din enhed, eller fordi afsenderen skal have verificeret din identitet." + "Denne besked blev blokeret, enten fordi du ikke verificerede din enhed, eller fordi afsenderen endnu ikke har bekrƦftet din digitale identitet." 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 4ae92c03ea..e03a51eeb3 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -122,6 +122,7 @@ "ŠŸŠ¾ŠŗŠøŠ½ŃƒŃ‚ŃŒ пространство" "Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ еще" "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚Š°" + "Управление ŃƒŃ‡ŠµŃ‚Š½Š¾Š¹ Š·Š°ŠæŠøŃŃŒŃŽ Šø ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Š¼Šø" "Управление ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Š¼Šø" "Управление комнатами" "ŠŠ°ŠæŠøŃŠ°Ń‚ŃŒ" @@ -172,6 +173,7 @@ "ŠŠ°Ń‡Š°Ń‚ŃŒ заново" "ŠŠ°Ń‡Š°Ń‚ŃŒ поГтвержГение" "ŠŠ°Š¶Š¼ŠøŃ‚Šµ, чтобы Š·Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ ŠŗŠ°Ń€Ń‚Ńƒ" + "ŠžŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ" "Š”Š“ŠµŠ»Š°Ń‚ŃŒ фото" "ŠŠ°Š¶Š¼ŠøŃ‚Šµ Š“Š»Ń просмотра вариантов" "ŠŸŠµŃ€ŠµŠ²ŠµŃŃ‚Šø" @@ -226,6 +228,7 @@ "ŠŸŃƒŃŃ‚Š¾Š¹ файл" "Шифрование" "Шифрование Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾" + "Š’Ń€ŠµŠ¼Ń Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŃ: %1$s" "ВвеГите свой PIN-коГ" "ŠžŃˆŠøŠ±ŠŗŠ°" "ŠŸŃ€Š¾ŠøŠ·Š¾ŃˆŠ»Š° ошибка. Š’Ń‹ можете не ŠæŠ¾Š»ŃƒŃ‡Š°Ń‚ŃŒ ŃƒŠ²ŠµŠ“Š¾Š¼Š»ŠµŠ½ŠøŃ о новых ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃŃ…. Устраните неполаГки с ŃƒŠ²ŠµŠ“Š¾Š¼Š»ŠµŠ½ŠøŃŠ¼Šø в настройках. diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 98a8aa1862..457aec7d80 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -374,6 +374,7 @@ Reason: %1$s." "Text" "Third-party notices" "Thread" + "Threads" "Topic" "What is this room about?" "Unable to decrypt" diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_de.png index 6c0d8d5eaa..f2b02ca79e 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c1196cd5631cae5cb944cd0cc6903c4758a8e331983b2bbd93500473733f004 -size 34294 +oid sha256:03d7fd58010b5eb1bdefef76648e08431728f51527815db9df58ee0010f871da +size 34304 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_de.png index fc9aeb0fa7..cf7fd18f5d 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b724d4087e37920bcb0ecf7812248f1dc31294da738866fed3000c63a4ec329 -size 36263 +oid sha256:bce8b45b24c38b3a991dffd06d1b2f79da728820ab93f649138ae071883aff60 +size 36269 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_de.png index 6722d77789..38a62af758 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c609a2f5a80242c1fa9fc20d6f6295a85a23e1795a2603c64bce035abc8da05 -size 45651 +oid sha256:241dd64dd76b17b3a024622963c809f8788e0c5ef5f841b9be500942e4618076 +size 45660 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_de.png index c1910fa5ae..5b6e58f735 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:831db915b860b285a9548e6469faa4d33445d7f79b28f6b54029bfdf2d61b4c8 -size 46567 +oid sha256:24ce85ea23acfd4d062785c013f5b1faa96d6ab75c1bab242bf03b6e6e330b78 +size 46572 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_de.png index 9a66f5b538..100e2139d3 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0c96581bc29034a47a345b5c5f215853ab5d5545b2d64124031fb930bbd9f64 -size 48063 +oid sha256:e36b034ca57ca657072a089fcb7f7cccd2a5ec9897f80077bba29f85f2dcc96c +size 48069 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_de.png index 6722d77789..38a62af758 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c609a2f5a80242c1fa9fc20d6f6295a85a23e1795a2603c64bce035abc8da05 -size 45651 +oid sha256:241dd64dd76b17b3a024622963c809f8788e0c5ef5f841b9be500942e4618076 +size 45660 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png index 7dc00e9c6e..2e87baac06 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b79450f73b04b2cb5a6cb674f303bba6326303ecca06f6a065112bc3b3e01db -size 46700 +oid sha256:0b1b8c43a078f16dd5424960c63bc42524ce73d5198834b5291f9bd874ee7b0a +size 46711 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_de.png index ce5528cf17..5f28babc08 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44fa3cfedf5f3b943fbc7ccb8a7e88163dd97d7a314f1a38e339658bfd84f741 -size 39853 +oid sha256:d25872cb05d6d9b0cca7c579f67e531a059251ed033b3fa10a8969d161c9b050 +size 39859 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_de.png index 4a0d1f93b2..81083ef1a9 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60f136a8ac494703edfe2f727e22befd07ffced587621ceb8b39136c3025fc4c -size 41511 +oid sha256:d2659371297c436c5aea18011221c081ec94299ba6a5643f5fda0214372b3096 +size 41515 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_de.png index da5814af23..9ba16e11d1 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0c93f1419921ce124a015b3e6ca8dbed714f0e8eb7aa55d2e33e5fde2396ef7 -size 35296 +oid sha256:1845ce37a3c2cc763b745caeb6cfbc094b6bd65a3c8234dc8173a13c5377e038 +size 35299 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_de.png index b3f0b141e5..7538d489f0 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:297914ef0da135e7294bb7bc476f581f2f28cb8cf4d8756b6d1379d1893b5c6c +oid sha256:abcd7267209f3ca0881cfbe3c9457f024d4368a1c8fc6bba8a00ab89e95ffac0 size 37563 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_de.png index 8aa5a5b419..0608a5a46e 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e2bfad23495d22ef4ccc316efb4af24de9ee26731a39dc1cb665bfa7b1900de -size 47303 +oid sha256:099f4b603ee07216e66a75d5d08b8f17084648526ac14e4e611c7c090260b8fc +size 47304 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_de.png index d1cc642217..62300fdbf1 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aec7bbe40f667e33c901290a357c0bdd35042b165e202f9f865d67587b38cde3 +oid sha256:dc0b352e7c81e7e6389985c4c29d1a7074bd733e56789f3f675bbecd6ff17be7 size 48289 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_de.png index b261d63af0..fc8a1452d4 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68cf296625cf15e2fcef1a02fced8e68e3357af7211d66b7731ea198fa4c3440 +oid sha256:800381effd5dcdd3f41d28defd29cb21c99d254de86a91c1e7f60f476a4e393c size 49863 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_de.png index 8aa5a5b419..0608a5a46e 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e2bfad23495d22ef4ccc316efb4af24de9ee26731a39dc1cb665bfa7b1900de -size 47303 +oid sha256:099f4b603ee07216e66a75d5d08b8f17084648526ac14e4e611c7c090260b8fc +size 47304 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png index 1e693e765d..b47aaf7358 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e41f2e18d265c3ba444041b286dca3e1973e861469d53f3f0933ccbfcdea5c5d -size 48394 +oid sha256:79db769c4c524aa2831ddf2e714102c0f1a5de1a7855025e67598c8f261e65da +size 48388 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_de.png index 5f5d5a50f7..84c90cefef 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b3e812737af7688f1cc3ac6e251a0fc56b631754888760f960be8cf1174c24b -size 41186 +oid sha256:631556267b57adf739438e7a9c094c411273de3d74113216064268926499d292 +size 41188 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_de.png index c5c4572551..13ddf126ee 100644 --- a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_de.png +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:454047441aedaf4eb85fd379acdbd0b9618ed348bc2ab876d92b963bc6ea34f0 -size 43106 +oid sha256:d8c0999d16e140465ab18fff34650ac850cf650316f52b4a3dd9145e6f928d04 +size 43107 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 57b0b95a3b..e7b089068f 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:77959d24fd7c52c4d63090e51d189bd6c41c9c350c1a4c97a2260c05b226c119 -size 86868 +oid sha256:e46c26ec7af7c4d1c1bafc0fb8bda6ef4afe7dcc6ceb8a5a38f2872ccafbc6d0 +size 86687 diff --git a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_1_de.png b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_1_de.png index 5b2f0bbb1f..0d394678ce 100644 --- a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_1_de.png +++ b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53a21b0c20ed1fb442fdb8d860805ee8f476cb2f527d571b07084751b58c762b -size 39239 +oid sha256:c50c374b59c957f4e007d9548c2e03ffb622fcba3de9bb0adb2e36336114263b +size 39053 diff --git a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png index 5b2f0bbb1f..0d394678ce 100644 --- a/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png +++ b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53a21b0c20ed1fb442fdb8d860805ee8f476cb2f527d571b07084751b58c762b -size 39239 +oid sha256:c50c374b59c957f4e007d9548c2e03ffb622fcba3de9bb0adb2e36336114263b +size 39053 diff --git a/screenshots/de/features.home.impl_HomeView_Day_4_de.png b/screenshots/de/features.home.impl_HomeView_Day_4_de.png index f200461dc7..40500e7b72 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_4_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19266c73ca346e8a290c9eb4091cd5088b5569710a31d06353782be071c03fcb -size 58359 +oid sha256:55944dde4104ac2de65a11ab041d813416a21aae25e4cc21b9f624a2d33a80c0 +size 58447 diff --git a/screenshots/de/features.joinroom.impl_JoinRoomView_Day_9_de.png b/screenshots/de/features.joinroom.impl_JoinRoomView_Day_9_de.png index 3730e14b8c..950394d6ef 100644 --- a/screenshots/de/features.joinroom.impl_JoinRoomView_Day_9_de.png +++ b/screenshots/de/features.joinroom.impl_JoinRoomView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f80183fc0e3b5b06b51bcf58f4547111d3df1f800aec777fbab41d9d7eb51a24 -size 42252 +oid sha256:b9b94629caba74d3fa8f9d939edc441b687c6496001b185c6b7dc4ba13a197d4 +size 41978 diff --git a/screenshots/de/features.location.impl.send_SendLocationView_Day_0_de.png b/screenshots/de/features.location.impl.send_SendLocationView_Day_0_de.png deleted file mode 100644 index 787f11c872..0000000000 --- a/screenshots/de/features.location.impl.send_SendLocationView_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6be1e5c5f4abfdae4e8c8e059ab6bd23808d014c76a029762f3bc213935322aa -size 19235 diff --git a/screenshots/de/features.location.impl.send_SendLocationView_Day_1_de.png b/screenshots/de/features.location.impl.send_SendLocationView_Day_1_de.png deleted file mode 100644 index cf4202ecdb..0000000000 --- a/screenshots/de/features.location.impl.send_SendLocationView_Day_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9666da59d98a5c1ea6c786d42d5f7ecdfacef41f795dd9481c8b207f00e5e92f -size 37893 diff --git a/screenshots/de/features.location.impl.send_SendLocationView_Day_2_de.png b/screenshots/de/features.location.impl.send_SendLocationView_Day_2_de.png deleted file mode 100644 index 43685df0a7..0000000000 --- a/screenshots/de/features.location.impl.send_SendLocationView_Day_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1db33582d79aee02c96c99e1c42149f91d5bc7a62d1b095428262b03619e1c4f -size 34219 diff --git a/screenshots/de/features.location.impl.send_SendLocationView_Day_3_de.png b/screenshots/de/features.location.impl.send_SendLocationView_Day_3_de.png deleted file mode 100644 index 787f11c872..0000000000 --- a/screenshots/de/features.location.impl.send_SendLocationView_Day_3_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6be1e5c5f4abfdae4e8c8e059ab6bd23808d014c76a029762f3bc213935322aa -size 19235 diff --git a/screenshots/de/features.location.impl.send_SendLocationView_Day_4_de.png b/screenshots/de/features.location.impl.send_SendLocationView_Day_4_de.png deleted file mode 100644 index eddcfdc5a4..0000000000 --- a/screenshots/de/features.location.impl.send_SendLocationView_Day_4_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bdbfd52bef468588d3655706a06c78d7c9fe6dab354a832b85236574d77af112 -size 19444 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_0_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_0_de.png new file mode 100644 index 0000000000..26a2d11771 --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e80b99b89c442b8126cf80c8497b524b03012075763dd34f646fa1f7850a5a25 +size 19956 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_1_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_1_de.png new file mode 100644 index 0000000000..e1f4b27424 --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94bc010e69f70262da8f693185bbb4e5ab65c1443ffb04409aad4b4ac6d6977d +size 38635 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_2_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_2_de.png new file mode 100644 index 0000000000..5b33246329 --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9fcdaa31d82e5e677b39ccea11767febe8d51789d410e0934b07ce27ab4033f +size 35151 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_3_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_3_de.png new file mode 100644 index 0000000000..f4290dda6e --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2eb237f3bea51645310fe28e66a374ee7eea722d262261faf7a2d4ad7bfc9515 +size 30400 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_4_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_4_de.png new file mode 100644 index 0000000000..26a2d11771 --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e80b99b89c442b8126cf80c8497b524b03012075763dd34f646fa1f7850a5a25 +size 19956 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_5_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_5_de.png new file mode 100644 index 0000000000..bdd4cde724 --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e17424dbbfb6a537bcd285ab3d4a4a8567a61cba89b17b7ac1caddbc26dfde6 +size 17320 diff --git a/screenshots/de/features.location.impl.share_ShareLocationView_Day_6_de.png b/screenshots/de/features.location.impl.share_ShareLocationView_Day_6_de.png new file mode 100644 index 0000000000..7967b79a1c --- /dev/null +++ b/screenshots/de/features.location.impl.share_ShareLocationView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f148e3b2e061cc9cc1e3a6568f4452175b51341a2c317aed2c52a355351cdff +size 42513 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_0_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_0_de.png index 1e8329391e..d4d8b13367 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_0_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7023f8cfa5fcaf68d44790813287382df6b5f496e1c6bc3025f5e6f280b82f85 -size 11123 +oid sha256:c27b436e8284ef32e2d4fe1285587f1580b4139b6e098d9e37e976c98f595057 +size 19318 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_1_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_1_de.png index 85da5bc99a..61d38bcadf 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_1_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4976c47e82967168892ef6a0125210b437aa5a2bd80f6100979a60ca365c259e -size 32420 +oid sha256:c0e8730caeac7c344ae3d7c605aa944a6b8d021b5f3b8cfd387cf9cc2814c6c9 +size 40339 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_2_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_2_de.png index 53aa498533..f3502aceac 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_2_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1befcf4a87a8aa3c925e55d3ae8776627bad230cff5e09f6c8d33172749be313 -size 28793 +oid sha256:4b70b5cc45b554c282a435f59d5311483569ad6be9875f25a1b88e1c9119b264 +size 36812 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_3_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_3_de.png index 1e8329391e..d1aa86b7c6 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_3_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7023f8cfa5fcaf68d44790813287382df6b5f496e1c6bc3025f5e6f280b82f85 -size 11123 +oid sha256:016809a14091abf8554648ea4cd45945541395772c540d8aa8b04a24c0190050 +size 32120 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_4_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_4_de.png index 91776aecf1..d4d8b13367 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_4_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32b1ab1cc6703376e1649d5b4b0288b142d954d7cbe02fd966a523e2c7b01f43 -size 11254 +oid sha256:c27b436e8284ef32e2d4fe1285587f1580b4139b6e098d9e37e976c98f595057 +size 19318 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_5_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_5_de.png index 5b2e833a43..a0d42acd55 100644 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_5_de.png +++ b/screenshots/de/features.location.impl.show_ShowLocationView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46d118957b387eff49efd968202186592087e32e01859b3c84f0f90b730e835a -size 14832 +oid sha256:10244806518a4f64985be17fa5814d1523ef8796398a02632d48bcdf2d9daf53 +size 19451 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_6_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_6_de.png deleted file mode 100644 index 9942a70172..0000000000 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_6_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ef794ae82eaeda53e7300b4c935d9ce7f4487b204ee78020bd4f518f816f7880 -size 23288 diff --git a/screenshots/de/features.location.impl.show_ShowLocationView_Day_7_de.png b/screenshots/de/features.location.impl.show_ShowLocationView_Day_7_de.png deleted file mode 100644 index 02f54e7e52..0000000000 --- a/screenshots/de/features.location.impl.show_ShowLocationView_Day_7_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d525359e7d0a5dc0dac54f05acf77dba55528bc3cfd614c047bccdd670267b67 -size 25989 diff --git a/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_de.png b/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_de.png index b46483bee6..80e1c0e9f0 100644 --- a/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_de.png +++ b/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0d3451e07ddc21d22d59ab932075b0b957f7a51903f373922193ade95afb43b -size 54648 +oid sha256:58932b4453c81582a8f3bd4e47a4dc37355bc65ce23413715d240212e44c5dbc +size 54567 diff --git a/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_de.png b/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_de.png index fe5e6a62f3..aca8462ace 100644 --- a/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_de.png +++ b/screenshots/de/features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ad8ffbf4727694e35b4104a0329443e4087ebfd780a15c0b2680d14fb50376d -size 65291 +oid sha256:b3da0fcc021270fe7cfde72e03f44f9c95428f18673aa86bbfb11a6acc0b344f +size 65207 diff --git a/screenshots/de/features.messages.impl.messagecomposer_MessageComposerView_Day_0_de.png b/screenshots/de/features.messages.impl.messagecomposer_MessageComposerView_Day_0_de.png index ae43fa0476..e7fbb21056 100644 --- a/screenshots/de/features.messages.impl.messagecomposer_MessageComposerView_Day_0_de.png +++ b/screenshots/de/features.messages.impl.messagecomposer_MessageComposerView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9eaef8876d48f81ff763ad24c6f4ae7aa2dd56e8968d75f2a1751c09805fd792 -size 18168 +oid sha256:ab856d0a2de029924cccaf9f2285f3178315d83fb12e02f7f71d9c69fdddc5d1 +size 17989 diff --git a/screenshots/de/features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_de.png b/screenshots/de/features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_de.png index 68dcee55c3..807e16c40a 100644 --- a/screenshots/de/features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_de.png +++ b/screenshots/de/features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4b1981984e8edde71723dd40849471b514d101b3d545b0a6132bea1cda0358f -size 43592 +oid sha256:bbdd0d31786b29709c02e9f35191af1334b6f6a32cc0614a833f79d47551fc70 +size 42687 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_de.png index bc903778fd..538acbb4fd 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:023e811a9fa6157440eb00ca584988273efc2f37ed3804208bf5aae8b9136673 -size 364436 +oid sha256:180a33d511c0bcea775972eb4c0f80856d40657d0683eaee67e3d9b58687ef3e +size 365444 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_de.png index 628521bd47..7d0a21c3d6 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6257478d8e46e942ca037b1aa178477e188edb9777d67a3e7560929d6aba8880 -size 370034 +oid sha256:e2d3bbb762ad093c0e60d1bb1f838d078449a1f3d733771f35660c3bbe5b374b +size 370934 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_de.png index 792aceaf60..de58d2b1bf 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc5e553875d40920c9a9066c25ba6094238a7894aeb26ab144ee4cd9083f1754 -size 363641 +oid sha256:29c9f1d6d7972e8fb27701407eeb6febae153e92e60ac21f60a5bcb01beeede8 +size 364778 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_de.png index 0053487297..40d6fe691b 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e1fb4257bed537387bda20ecb17ded43f4f9edfa1c3280b58fdd8a3dc9c91819 -size 365658 +oid sha256:1fb43a66477ee416f6e8bea4acdecea322fc9cac09c5cc4c8fe6644fdefe78df +size 366590 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_10_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_10_de.png new file mode 100644 index 0000000000..ff53dce724 --- /dev/null +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_10_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ebbbddf29df78c6a6b37f931052cac67ea7ae1c875e2d75fa6ae8aa1683971b +size 87348 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_11_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_11_de.png index ff53dce724..23715fd683 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_11_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ebbbddf29df78c6a6b37f931052cac67ea7ae1c875e2d75fa6ae8aa1683971b -size 87348 +oid sha256:0914e81c505541a4f000240469e746964c5f476a7884403616015fab62f23663 +size 51743 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_12_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_12_de.png index 23715fd683..44e66cdc1e 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_12_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0914e81c505541a4f000240469e746964c5f476a7884403616015fab62f23663 -size 51743 +oid sha256:fa15ce3aa51c83819e6fbdf235e6f732b0db187ea49344279b01614efd9ff6a3 +size 63456 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_13_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_13_de.png index 44e66cdc1e..04e605318e 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_13_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa15ce3aa51c83819e6fbdf235e6f732b0db187ea49344279b01614efd9ff6a3 -size 63456 +oid sha256:961a9289be61a16372087c645302e4043d71f73c4440e24473941a9a6aa41daa +size 48104 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_14_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_14_de.png index 04e605318e..e6bbd0bdff 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_14_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:961a9289be61a16372087c645302e4043d71f73c4440e24473941a9a6aa41daa -size 48104 +oid sha256:fb03835fff5c4d27009fd19af5494b71501445184f6cb984e39fa175e430fbbc +size 72082 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_15_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_15_de.png index e6bbd0bdff..7169b684d9 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_15_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb03835fff5c4d27009fd19af5494b71501445184f6cb984e39fa175e430fbbc -size 72082 +oid sha256:f9bb51eda6e69e8cd532a3adebbd33267580fdccc904c91e741cb2e8026f0b79 +size 57796 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_16_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_16_de.png index 7169b684d9..c3563a3472 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_16_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9bb51eda6e69e8cd532a3adebbd33267580fdccc904c91e741cb2e8026f0b79 -size 57796 +oid sha256:5b88d255f070df4fad03371c64ce31e080a35999352a6a87cc10f83d8d5da99c +size 64506 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_17_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_17_de.png deleted file mode 100644 index c3563a3472..0000000000 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_17_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b88d255f070df4fad03371c64ce31e080a35999352a6a87cc10f83d8d5da99c -size 64506 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_4_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_4_de.png index f63e3636a0..ba7d60941b 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_4_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b28fefedd7a34cb758217de7b240b536abf6f485bd256fd718ebc181df45e15b -size 70537 +oid sha256:e916a49d3cd4d81d8ec5f3d66f0b930bfba6e9c20f1b9c5f7d4c0bfe51895036 +size 67398 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_6_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_6_de.png index a624c779b4..0d70a656c2 100644 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_6_de.png +++ b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa1490b35cdd22c0b01db869e8bad73195481fa2a2e7e61eb289e3f51bfc6200 -size 73417 +oid sha256:86fa2e5742ba38c173add0921615a18c1271caa783fd1a505c80a06096a3c248 +size 71646 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png index b3df3736a3..6a6d9271cc 100644 --- a/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png +++ b/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ddcd24501a9e91f4a42cbffd60693a93d2dd0c2bf28e469b1b4ea460e2630d17 -size 67293 +oid sha256:d5c26f5383e1d079f5fa8a62baff668032181568a52bbbbc90bc2ee5d70d78a7 +size 67208 diff --git a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_de.png b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_de.png index f085e23212..9fc37666a6 100644 --- a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_de.png +++ b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c823b266179d70fc5b6b3a3b1e0654536d1971fbe615f9db99fc8203049bf5b -size 23526 +oid sha256:2fc98a42e6af1c52bcd185592680871187a5cc942de9eaac694c0209f50a0c64 +size 22678 diff --git a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_de.png b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_de.png index 52c0695203..2144c61e2d 100644 --- a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_de.png +++ b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6c6e0585e05d474d7797176d1f8222654d1eea1522bf508b353bf6b5694eaed -size 65127 +oid sha256:6f493c136e7284783a35253f88a752ed973d628786e7c0db037a8c3a577ef8a3 +size 69694 diff --git a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png index 293b43a7e4..0e09e3da59 100644 --- a/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png +++ b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06b30b3ffe792671b4a68044fb8b4c0deb9f1a0c0e121f166e2e4c50430f6c98 -size 35065 +oid sha256:f1394337ff80f74e9f4b6c5c2c947db462677f2957e0b73d2e919aabb6d2fc99 +size 34412 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png index c2ae0556f5..e38435bab5 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ba073d0fe9e1119e008a086fda234bc3451df4685a4d4704cf8721244f92e10 -size 46184 +oid sha256:17ad93c86555868ac098ce3beadb8dbde57c89af9bc2caec61df1f3596325ae4 +size 46178 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png index 6d58ebeeb9..23fc5ecd1f 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:723d8bdb06037c0098aa35fa2a8300a9ecee7367b5ee608bef7216dac4f46d91 -size 44761 +oid sha256:d16ff2356729e9d5aea99f00b110efff09d6c0beaa33e100846f3c56cb0fb0a9 +size 44757 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png index dc74aeddda..fa145bb3cd 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9864cca2481e1f2f02ee625fbd47f3a182fa997cc917bc842ed893c1d2eaa151 -size 43560 +oid sha256:e8c48700213f1ac24b20c08d8585bea693ae08cf4a3dc91e6ac6aa08c1a02cb4 +size 43518 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png index 2630d505bb..564d0ae6bc 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1aca90256973d9614b6dbbeb665b782ebf3c59922c3fd569552d58d8437f54d8 -size 45347 +oid sha256:6f97df43c4f6e479e7ccdaa94d0e817f2ab3f02cf21986df1af09805eed8bd59 +size 45340 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png index dca83692da..90d69eb98c 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb22c1fa6e30e4fa2f9500fd33f3aa44bab2c2a1eb1374b306a216a808c96192 -size 45260 +oid sha256:75b4afed84d26d914eb82cdef4d9b7757d7cb27b0ee938c2bcca48d10553ced9 +size 45253 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png index ad0dceff1c..85c3b70cf2 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d933933bb693c3e227a750d5db76afc227df9ee4932823c6aafe99ec98e6dc1 -size 45838 +oid sha256:b7d85799138c9367a1229f36d90481577f08e027c4e946789f48e098b3927a0e +size 45832 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png index 82316c99e6..133d94e153 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a6f8f86d9a770a893949c7bc1762e3e05c6940be58708f5ac7a1704ca84debf -size 46369 +oid sha256:3ffbe5ab44b8cd51b94d766ff8bf0cfe05b56152d94a75d2858aca6b25db0bb8 +size 46364 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png index b70917c986..95a9128cc5 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5978469c7701bfcdb1c4f5af0279ccd712c1c9a7ac17d26751659d0bd72fc7b -size 45626 +oid sha256:18f4ef21e7a652f29dc88206e514ad600c05cc9dd2a6a3532e4aa3e68894d7ba +size 45621 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png index a6ac629dd2..eee91513e2 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b81a4f9a425c64ff9d3bbe5f61fc9abf46d0c4d5f746aa8b35140dd7ad568a6 -size 44844 +oid sha256:d04a9c799ef61bf131131e527c8734dd8ca67880d92a9ad121b576bc11d4a992 +size 44835 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png index 6d2de679d3..d99db83de0 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8608f7c43d21b688f60f7416f144df912fb7f8852949cd9fdc6752b47f9f0338 -size 42918 +oid sha256:cd41d6b3943d4c5e74090acb90a712b930be74c49c6a39fbe2f3b60e90855fd0 +size 42886 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png index b1448746d5..d02979f393 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a9bba827ce7181ac459aa41f933bcb1513a8adec101b89a7557b4759f1740fe -size 42871 +oid sha256:17e33f973d9e33f6e06e7b2b66d448d66183a353ed76c1d7712a13e2af9cbbc4 +size 42839 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png index 956fc80005..e0520466b7 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:941b9293c96017d16e5964bf13f5b6b7954af6588a8dce2a8f731bcc3efe0321 +oid sha256:ccc14ef7b66c52afcb6d806b4d8d170ffb83b7817a5ecfaffd706853bbc35cf3 size 41743 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_20_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_20_de.png index cdf129e144..d8814411f0 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_20_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_20_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dc02ed20454ffade7a393956c0dcbb6f15a7d7012c0322cc43291580ffdc99f -size 47790 +oid sha256:33521284c24815367a302bde9c49b2795ecb5d803ac322220f720c5269605ea8 +size 47818 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_21_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_21_de.png index 4392889de4..e89ffa97bd 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_21_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_21_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eca6cd07f5eab788aeb07a35fb23c8f4ffc316aa9dbd1b48efdf00d16e6b4093 -size 47567 +oid sha256:4f16ad28caae15b4bd13fa61dd5b95450a559b00dc005b157fecf44c9b7df625 +size 47553 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_22_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_22_de.png index 9f391af648..3ab82edebb 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_22_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_22_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:450d628e5540ec8234d6c3aa33cd657ff51a56b5518004eef628eab92328b616 -size 47221 +oid sha256:5c493224b3437d144e064f91a9dcc97779953cddd81aa5884631ca0046d72dad +size 47264 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png index e53d7fab40..15c3785853 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6411a8af9386bfca9b171e16b60231bc51c0a7ed92ff462918a1342251ea65e0 -size 39459 +oid sha256:6ab93cdb57a580a52ed48dde779355440d6a67412f9699927a8d4214388fc4a0 +size 39451 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png index cee674d4a0..ac8ea4aa9b 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:731fc476ed64dcf665ccc999072be646b04b58d7e440ba96e38cddf6953f08a4 -size 45410 +oid sha256:2d1c6f0c3898e000774de48cd7590c44bc11c297163735f16cc2dccaaf23e538 +size 45428 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png index 8cdd7726b9..85b757fb86 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53aea24a421f5c5bdb2b4b0cdaa3b73f45c2747abc2d547c52b35234bf1944ae -size 44602 +oid sha256:647eaeb0c9ddce71bf99e382fa45bfc560affe38e8581e12016a1e5a37e270ba +size 44587 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png index f9a596640a..ddac91c4b5 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fbb251010c11e7cf41cd9d772628eec858e2eb7eb102f0d07a177f25d7e0e42 -size 42559 +oid sha256:2b129c0c7e62d3874d1b7e466dbbca271873b20d3155981eafdbd9c33202eb04 +size 42527 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png index 346aa30d3d..a4d831a49c 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a898591cee5b687baf9ec6d1c4fa1c0de34b99e45ddc1541de15d468c1ea1b1 -size 45985 +oid sha256:35aab3535b161bb3b111a9a352f510b43a25f9c98a7e5648aa3a380cd8402063 +size 45969 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png index 39f289f1e2..a85951f6d6 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07d62137742d97ebd6f1ca605f8239808d063db2a5af5a217fafa9156a7d8906 -size 46085 +oid sha256:eb393ca334e520249176e392cbf9f495c8651904f2e03680bd740f4d9b1c1ade +size 46076 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png index 064953e54c..d8ac60f111 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bbc17b6609505a390fe0baae91706366deeb8bbb41bfe8493e98e23a1753c28 -size 45479 +oid sha256:6d420ac1d49b4f2a47d00e6fc273e2f2768b14a05f0d10c8c655cb492abfe142 +size 45474 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png index 77fe390317..3ec8b090c2 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f9836b0fdd3bda742e2b4c7aa7f724f1d6dbefb748d4ed31ba6912ab6600f2b -size 44166 +oid sha256:8435264c98cefccc80e7a4bd32d903708e878f4c4ad2686aa35df8fdb9324882 +size 44159 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png index 6fd394851a..8d470aa1eb 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f006c30451416d0a41c3d902f7c9dad8b4d404326e623534ac7a09fe5b2699f4 -size 47231 +oid sha256:c0cdc554f6e3ce1725e2459ca0c6133f7f14a15d730f190bbbb795eb11c0404e +size 47224 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png index 3346f21554..dc8f2611d0 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e1fe354a3305ad933daa95a65611335357ceb6599484e85ee4d3ce2f019e79 -size 45747 +oid sha256:d408175ca51c0b36ec01cd950b079467e29bdfdec9b18a1b81f1480ffff51e6b +size 45740 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png index 8028d785f4..5e1712b9a9 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f7d823c76b57b8d37cd86bf6dde6e61092dadeb03f65e0fdb3d9d0e7b016513 -size 44564 +oid sha256:3bc00b126e3820666bad9a4904b3956ab391a6af0f74ce30794373af1c654ea8 +size 44592 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png index eba1696597..6f725c591f 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15ec7bd1f0e7baa884e7e89aadc485a7ab02d80fdc2957c5ae10ad6369f3bbab -size 46376 +oid sha256:438edecdc96de067dfef71395ca0dbde45b5127f5a8d507dd4148f43da12f1c2 +size 46370 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png index c9813ac9c7..db3edbd7ed 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1818053ea53eb07fb96a27350bb0e59c8b696dc0a34ae16f7b814743d377f06a -size 46272 +oid sha256:2272a4633116a8f58a24273fe348e4cf979eb31fa78a641ea6da28345e358846 +size 46265 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png index aebb284744..8d78460895 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:966dd5700a19d89bb8192b153f381387e80094dab940fa876a4c4eafa73c23df -size 46776 +oid sha256:a45ea374ed7827a1aaddcb6b5d0eb344b4c0d79ae328099bdff79a8a3ef84b5d +size 46769 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png index 74cd663399..f7d40446e8 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ba4a4082698d5aba2e36ed11e50df97b59c2d85e09b53b1e3d534e2dc97c34e -size 47377 +oid sha256:d4ba031a35b259142083b6fd508b7ab15cf169f7f5b1535bd81ef7e4fbdc0a6d +size 47370 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png index 03fa90e4ca..fe75d48f6a 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d258cc980ddde7603d07c1d0ede66eb05a61215e8a9f7591083f44e3fac48ce3 -size 46652 +oid sha256:7e87581df1ada41c9b7b85f576da8c32f856203a6c48e7f40128fbf30c7a33a0 +size 46646 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png index 31d3ff96f5..56080a7551 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e1cd8ae0035eb0cda747eac54bd11e3d95b8f006e10c05752209b0aff5062e1 -size 46149 +oid sha256:d87b127824291e0343f53cf50a22f0e1e8b89e00be55ea5f625aac59f9109a4d +size 46142 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png index f8dfb9f0c9..e9d5014602 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc96bea99a5bf31bb0f742383cba458f14baf150845a47e1d14681c806c2021c -size 43913 +oid sha256:827747ea2eae177d460d615b9da37db515f635ed433567945e1d88cb39337594 +size 43944 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png index 16ce3617ac..8bf44cdefc 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b6d30a4661310b3de30ed34c55bbe37af245ccd0c363cf2b5fea7c66f058e4a -size 43792 +oid sha256:1765877cdc96b174cb7a2e087165c74d1ceca02137d0daa510ec247cc4f481b6 +size 43823 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png index 6de030abb8..52c52e8769 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5327a706c81ac518776c5ad183bf601c14c97ea7bebc9b7c52cd04a2919e40ed -size 42899 +oid sha256:6f3c5533e239f54302eb7867bda7571fd966b4c298be9ec48abad6a5025c22d7 +size 42890 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_20_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_20_de.png index bb4aea59b1..c510c5f777 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_20_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_20_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f989780ab77db2fe17b0e7c52f8d73ad9de1c336bb02b4dc29140a4cda55cd58 -size 48860 +oid sha256:abb0b25a08a6507a9b3c0f3ed79ca11b26dcc54a9350a0711f9385ccb0ffa29a +size 48855 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_21_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_21_de.png index 84672b20a9..aadf561762 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_21_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_21_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb5e80f50cfcf6e6eac762a3bde89bf474931ac8a10c951d480f354f6bf81875 -size 48581 +oid sha256:f615089fb33bf68a1f24bc1d7f78ba899ea80c5dd5e046b05df04055e7d15ed3 +size 48571 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_22_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_22_de.png index c8ed3fd3a9..2c22f9b92c 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_22_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_22_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aadbf1e409f2837387ea390c82ec8bf16a979e995d01bc0250cdf9d4bc7c881f -size 48252 +oid sha256:c9f1b2f0372b538dfc219ac8ac699347a199f0df903813ad1a97b7e158f50f9f +size 48241 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png index 83868afa29..22634ff9dc 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ffc68081fe2c9c391f71635a160559d4827f5ce69589d799ed499612e77260f -size 40469 +oid sha256:ab5386c966f4b5981bee9d39cd6a315bdc86dd286ff2c5e08aca4c5bb3304b23 +size 40457 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png index 7daf7e374e..95c8bffb80 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2fe91f0d2dc898b39893d1efb70a827197e59af026fe53badbd4b1dd9a7ad11 -size 46398 +oid sha256:39e4eab91f3d07daff1437991ec74005e7c79eed3f9b4ff71c154d68bbce3e71 +size 46400 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png index 69515bc17a..7574b9b61d 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3388b6b6f46a7c90f3c45568e22d7d795f91a8a5e3fc9fabe7acfdd99013f868 -size 45606 +oid sha256:49009a3a070a668b7487ce69b3bf1377ce113cf003e1571db3f90d8319ec084c +size 45597 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png index de53328c9b..00e31d8cd9 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8cec2bc057e632943ba3aa42fa427ad6f6e766682903d620067ab5c8437ef21 -size 43449 +oid sha256:9e268c85951e089414695eed071ec5c98a80030d130f92d8a934f815dcc75334 +size 43480 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png index 6620a09ccd..71787b6f1f 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a84cc9c31168887d8924044df0e558b4aeac360a52426027be5b5c1a020f116 -size 47082 +oid sha256:eb164e2c9796a1d12a0146b3fb67d29813be54d42b0628d17a323a525b866177 +size 47065 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png index e1ed2068e2..ed016c1eea 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65b9e404e0cbc2315d595febce884f11034ef7119ca76ae9dccbab4d2248bc96 -size 47259 +oid sha256:5a0b75e17e467d1a8abcb59f0e490c57e1bc538f10a6900cbff2e2c14994f0f8 +size 47246 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png index b0c9775ea3..d4eb3afff0 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:36cb6dee1515ad0239cd87969649d39ca53b528651565ce9f49461c6f7f12198 -size 46633 +oid sha256:cd5c0dbd3621d8936b4e7eaac29524fb837007daef330802d71a12c1978d973c +size 46623 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png index 472623e81b..3466e4571a 100644 --- a/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png +++ b/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6436222472999c9ce19fdab8e5ee9d10dbf846b2764a366826cb4150c0dd426 -size 45170 +oid sha256:706e54694211c141ad5cd505379f695504b2fa4b793a9aae5242d52f72b9aea8 +size 45157 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png index 547b9ac6d2..8c69f2926a 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c96373fa4553adb41fd650ddd7794addd57a2c007152bcd24a33a2677f692aa -size 29729 +oid sha256:efc41570c6e1c04f96a4226b629a55fbc979555cddc20e62659b57e9e9a516c6 +size 29702 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png index 830a59bc98..f3f3f717c5 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5acabb4f45503b9c685510dfae0ebffee07b6383d7471edc74a462bab952ed56 -size 24105 +oid sha256:420cffbe21d04b2e274cd5c6d24076f05a21081701a60925f7efe0aa64f82839 +size 24097 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png index d4f4218c6f..e963ada9fb 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1331106fd5cdb17e1a64517582e2017942bd30981e35c9104ed9691dad6f535 -size 30220 +oid sha256:2284ea6f41d947283f997d48c2532119c1562b606bdbf730bdba4755e67c28e8 +size 30135 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png index b9ce13764e..f1100ff0ed 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a0fae6a3d68c058cfe4cc4d0a7c395129262050f4c423dff5734318b6d5a5d9 -size 52439 +oid sha256:582e106bc388c89ad644b2899390e82e5740004061aec622b6b97aa1bac12f85 +size 49429 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png index 845659c354..0888d9e355 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7fb81d71260f2ac8568d8505f4ebfec1ad97e8001a94db6815e9dde859a38e30 -size 48491 +oid sha256:cca14f96f4ba493ce291f9f982d47a84d6eea3090e774bc4f2b1df63472db696 +size 76461 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png index 43681f14c0..b54c41f267 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d3e9968441f6189ec0e234c34178f7802ea4da778000338da3506ee428182ef -size 29869 +oid sha256:45bd842b590d153fd7c727b08e34f69c73fba0f2c73530f7726efae1386b37c5 +size 29846 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png index a2a0734703..5e4641cef0 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1067316ebeedc49b187fec61da538e07431612d5b38efcf8f7360023d4c34c1 -size 27968 +oid sha256:4a1d1b889880d3e4065b7de036c7e6a26f6817dd6268df957d948ff06aaa8c7e +size 27881 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png index 698dc47f17..9f16c22be6 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f1cb7f8790e0bd8ca61e137494db81295d6bf3fd6eec0f04983178a17c2bbe6 -size 25608 +oid sha256:45c2edc8bc542bd02c26c696c339855f8176afa349f7097f35cd9b5d6a45ca43 +size 25889 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png index 528eed4126..440f2a693a 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91592dced46d59ecbd6edb157ddb5325fb6a8a495a9434c2d878763f317dd104 -size 30930 +oid sha256:2f74a6693ce54a06ddb795f4787252cc35ae457eeb71330e2c3522aad64c55ee +size 30928 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png index 3f716d49eb..13f81454c3 100644 --- a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6d39446fb8d8889b01bb411d92022fcf80e04efa89fd9bee7c071de791f8213 -size 32436 +oid sha256:dc4d09a07b88320eaa41e006cd67c56a7e6d5459f15e0471b00b0cebf73f95c5 +size 32558 diff --git a/screenshots/de/features.securebackup.impl.root_SecureBackupRootView_Day_14_de.png b/screenshots/de/features.securebackup.impl.root_SecureBackupRootView_Day_14_de.png index 51dccd31d9..2e8f128b7c 100644 --- a/screenshots/de/features.securebackup.impl.root_SecureBackupRootView_Day_14_de.png +++ b/screenshots/de/features.securebackup.impl.root_SecureBackupRootView_Day_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8944a90ad9e5cd283b9a46547ffed79b932fc0fba9caa51a5d2e91021d302bd -size 66333 +oid sha256:4ff016cdc3ea47662f224c49fd182cc16ca3bb1e09191ccaf2c418ab93a358a6 +size 74302 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_0_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_0_de.png index 1b0d3b202d..9ac2444e4f 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_0_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae0a43f1e5cd9dac74a4bd9783d7dcec09acd8d972b5ab24f6f7b1afd55d0db1 -size 50203 +oid sha256:f8804204dff0d36762b0c02e9503f2e06b6be257b9e1c0c2af6df0c0fe2855b9 +size 50289 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_1_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_1_de.png index 853875b8ee..36817c5f75 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_1_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59af40c662f9dce190b7dea5b7ec52e69c6d7cc20d70ee9ea605ed730923f216 -size 50362 +oid sha256:a69c330592d208be768c7f607bede843483a92140155c974ad4a84116ebd142d +size 50380 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 e1425f18f5..40e51c9537 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:e648d7ad31cd4369f8230685a9e4a87b87116a9187502d2c224412d722d8bc75 -size 52276 +oid sha256:428725b17dde8ae30898299043e2d5e03ce63f516c93e440e660823fabd43e4a +size 52036 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 c46b7d0dc5..806bb43ddc 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:d7683c2be445f411fb2f5c408db5ffa6e40ff562c9cee757ce16b36e0643aed0 -size 61299 +oid sha256:ccd76b6702435a24f67ab28adc60b462acb2fb430daf87b6ddc53237940bb29a +size 61987 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_4_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_4_de.png index a02909f45b..75087f2a67 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_4_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0cb890656c62a8c0b5004a905d6614e89d6c395632b168f49047443c4853e62 -size 61924 +oid sha256:524f0d29e59175ceb996b81b98625e168033077b12541f8747fa6c6082097cdd +size 62629 diff --git a/screenshots/de/features.space.impl.root_SpaceView_Day_5_de.png b/screenshots/de/features.space.impl.root_SpaceView_Day_5_de.png index 8e0058a639..8a71650321 100644 --- a/screenshots/de/features.space.impl.root_SpaceView_Day_5_de.png +++ b/screenshots/de/features.space.impl.root_SpaceView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:208b78836148e8403ecfbaca6b3f14bbcec1756cb13ea0fbc00cdbb6c970659b -size 57796 +oid sha256:e338d699f2cb5d4645742e9dff3dc7cd3dec20d2ad75821bd3fdb3fb8e917a96 +size 57250 diff --git a/screenshots/de/features.userprofile.shared_UserProfileHeaderSection_Day_0_de.png b/screenshots/de/features.userprofile.shared_UserProfileHeaderSection_Day_0_de.png index aba971c8a4..b7ab99464e 100644 --- a/screenshots/de/features.userprofile.shared_UserProfileHeaderSection_Day_0_de.png +++ b/screenshots/de/features.userprofile.shared_UserProfileHeaderSection_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f20ceee8793c045bcad1c1f3ce30d6aa36ba5e688c8f8b14161849bc0bedff01 -size 15889 +oid sha256:4b8a6428ae3624826edb3917a78e641df0704e8c21519ac003ff27387d0e37cd +size 15902 diff --git a/screenshots/de/features.userprofile.shared_UserProfileView_Day_2_de.png b/screenshots/de/features.userprofile.shared_UserProfileView_Day_2_de.png index 2a37678990..e7254790cf 100644 --- a/screenshots/de/features.userprofile.shared_UserProfileView_Day_2_de.png +++ b/screenshots/de/features.userprofile.shared_UserProfileView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aeea0d322e256f499ddda7dc6cd40c2163f75ac7b9755d75289dde47f28b7c3a -size 25016 +oid sha256:f7bf1f5e039bdff2ba1da2678d57637564288733b9958042b86867350277ca9f +size 25025 diff --git a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_de.png b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_de.png index e8a6cb04c3..6463867d7d 100644 --- a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_de.png +++ b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d45be0f3300cc450129a656e28dd131c66e84fa36bf692a69441867d42ad562 -size 34110 +oid sha256:f85a57b51f5ac9d7165be8d83c414b8a1fce87f2bbbf4a345f145f01ba80e3f2 +size 34420 diff --git a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_de.png b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_de.png index 18a8311f9c..bf3926ade2 100644 --- a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_de.png +++ b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f3d837f5d0d5899f0a20b71dd8f39c1bc304bbebfb1b34e48f7b2feab805133 -size 25895 +oid sha256:e050acd07312ef4e19b85323ec4c061f9320fde6291a2818e58771257caf777d +size 25803 diff --git a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_de.png b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_de.png index ca4eb19234..58f0d723a0 100644 --- a/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_de.png +++ b/screenshots/de/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:070a29bc9f0e4a9148348eba4ed164be33f0a238b892caee66343ad43c16a6cb -size 25601 +oid sha256:cba578353fc5d7e9e9327b0ebc89b8aad9e3743014b3fffb93538bb89fb9026b +size 25479 diff --git a/screenshots/de/libraries.matrix.ui.components_OrganizationHeader_Day_0_de.png b/screenshots/de/libraries.matrix.ui.components_OrganizationHeader_Day_0_de.png index ac7f62e753..8c65dbd7b3 100644 --- a/screenshots/de/libraries.matrix.ui.components_OrganizationHeader_Day_0_de.png +++ b/screenshots/de/libraries.matrix.ui.components_OrganizationHeader_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df1613037f5b06b6cf9886056977d2ca269bbb09729d9aecdba9915c77cbed78 -size 41954 +oid sha256:0a8a0630b584a45d35879c3d729921abe6d810245cbf19ed74fec7d24c702d40 +size 41390 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_de.png index a46fd0d98c..07b95441bd 100644 --- a/screenshots/de/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_de.png +++ b/screenshots/de/libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d26f94621d75228ea9bdee2abc8616b378a64cf8b63b7fb043f32fdef61082e3 -size 18046 +oid sha256:fcf290de055889a30b6859a0815655b07ee96e600e241ad18af768ba7d0691a2 +size 17777 diff --git a/screenshots/de/libraries.matrix.ui.components_SpaceInfoRow_Day_0_de.png b/screenshots/de/libraries.matrix.ui.components_SpaceInfoRow_Day_0_de.png index 90d4f208c7..47ae5e64e6 100644 --- a/screenshots/de/libraries.matrix.ui.components_SpaceInfoRow_Day_0_de.png +++ b/screenshots/de/libraries.matrix.ui.components_SpaceInfoRow_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1472df8a860358e2193de329ca363a85cede2c65dc51b7182545152f9caa036c -size 20165 +oid sha256:5f245cfa43b2310ab533005012debe347d196b4c177e696ff4399c8431397113 +size 18057 diff --git a/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_de.png b/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_de.png index 6a40ec4ecd..a0198d4d9e 100644 --- a/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_de.png +++ b/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d350923703149b79d86d1029b1f415eb0e90b69165956ae44a23acfba203aa0 -size 8839 +oid sha256:de86d0d2cfcb6c2fcdc1fa3ea89a31ccbdbeaad7068fb29992c2989e2f3cec20 +size 8789 diff --git a/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_de.png b/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_de.png index 97b55075c1..6e431b335b 100644 --- a/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_de.png +++ b/screenshots/de/libraries.matrix.ui.messages.reply_InReplyToView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83fe63b22d68a39a7d404ee2f6074c7adcab79f16e11655d08a37ac3065be59a -size 9327 +oid sha256:4d2cd5afa60a792cc025b6eb580556162b06f03e0bd15b1dad8fa5294ce49e17 +size 9315 diff --git a/screenshots/de/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_de.png b/screenshots/de/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_de.png index cc6bf7ea12..92f956925d 100644 --- a/screenshots/de/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7515c7be72796a399518d0229c4c656e8bbaa759f5710782926b393e65a0dfec -size 52291 +oid sha256:40f902114622ce212797bd9c0a7cf8fa9d465cacf1f32af99422558b35907d02 +size 52217 diff --git a/screenshots/de/libraries.textcomposer_TextComposerAddCaption_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerAddCaption_Day_0_de.png index 5ffe8738ed..c36a2ce217 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerAddCaption_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerAddCaption_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:17b1cc7c68f7f692d819b05cf2ed01454b2dfdf33d847dcabdfe3823aa2858d5 -size 58106 +oid sha256:e7326fadd145ca624810e858cc3413fb56a25f875854b7d2e75cd7e1d1b4134f +size 58018 diff --git a/screenshots/de/libraries.textcomposer_TextComposerEditCaption_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerEditCaption_Day_0_de.png index 15e163db41..f9cbe155c1 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerEditCaption_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerEditCaption_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4c0e08d0814afded19cccab71e3e25f93bafbb23e285a2d9885b55db95513b3 -size 56085 +oid sha256:dbb50973fb9da0bb43708e3e608de3a22a301a2dc0d8c699bd9e0f59d5b44f20 +size 55991 diff --git a/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png index 566e8a69fe..c6d05fe805 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a28623ac9a17d8d707a92b229e106836cbc04de108598f573e8ec8e89e3d997 -size 65096 +oid sha256:987e6f677fe5412dcd5c94a883bf5966b18d048b31f189614ae2763823e319e9 +size 65017 diff --git a/screenshots/de/libraries.textcomposer_TextComposerEdit_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerEdit_Day_0_de.png index cc6bf7ea12..92f956925d 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerEdit_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerEdit_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7515c7be72796a399518d0229c4c656e8bbaa759f5710782926b393e65a0dfec -size 52291 +oid sha256:40f902114622ce212797bd9c0a7cf8fa9d465cacf1f32af99422558b35907d02 +size 52217 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png index d3d070cca3..9b074e7cae 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dd776bc6cc47e98bb697fd45118580d809504af449e66f8e6233e239746635e -size 73608 +oid sha256:5aea70f07d78c618613628503eae01783fef2561e963e4249ab89813886ab8f4 +size 73530 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png index e0068535e0..c5b0d39e9d 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b318e520274fa61235bb3078a8e43f50f00cb3e995691f7c250aafcff34adf6 -size 60221 +oid sha256:41a9554ef3d3c8a9cf0b2234335728528b212caf954086ac7f8767fe795ec0c0 +size 60076 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png index c78fd312b6..bcc10c35e7 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4265b64af0d85d26fee18c5840c78dc248dca6c0188f7d05599a17533bbf7c56 -size 73032 +oid sha256:4bf87c47d0cee012847b5f0a0264f6f4e4cb948f965ad28af58fa5dac6b7e3a6 +size 73133 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png index f3f25e7b89..7218918f91 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0046b0b393a115565f40ef8e3d56e44b2f0e60bac1c58f460c5b0ccc51c0758 -size 81592 +oid sha256:abd564eae0efae348f0cafbb5749879b29f2d2b0a82eb645cd0db4e75ada4ff3 +size 81908 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png index 92ee2953f2..e3d9c74293 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a67d6255f9b0f17dfc39655a9006d616e5a000edde5c43675f9c05edbd61eb8e -size 62741 +oid sha256:1aa1be60455968000254246a1b307c8336e2c8e36cee5122e159254adeacf78e +size 62919 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png index 3d9ecdc028..af6d69fde2 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9bafc0bc7aa73c3d984e01b4d94a1f2a50a2457add0b202b89bec0acd5f8a66f -size 61646 +oid sha256:1bb0d795e03931704043807bedc666f129ca23aa60b2690957588b15c2a6b5ff +size 61770 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png index 34d58521be..33ff1188ae 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1afc95b901ad97456215f1a2f8fde7fe35f5837032b906eea6053f14814d4218 -size 67238 +oid sha256:8a40c856d3959ea432fa4a5bc5624e10005d8f405c5b5c199acfa38c3107035c +size 67354 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png index 7696ab1dd2..b100db999d 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:455dc658af36e11e5175585c6965731b4493428596fb5ef0b77b6b89abd007e4 -size 90662 +oid sha256:797c78b06b51daa6088b94f38e536d59b619340a270bf7a4f8cbbf08c6c44be8 +size 90472 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png index 409f5c23b0..2c0063362c 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4514e0bd54db4822486ed0d762768f186cfb24611fd6a8161567b17bd20462a -size 61057 +oid sha256:9c431aa38578a656d8f1bf8f58d2fe8534772ed127c2ce102b377052b007306e +size 60994 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png index c20f81e2a3..2141974bd3 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6408e9a851a3976291270c08a6cc3ec30a8b1148f2034b6fa7c5bc8a66111b40 -size 62277 +oid sha256:ecddf9e9d5c75c2675235b5399d899cb8ae24383d32ea1bdf1899cb95fb8be54 +size 61138 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png index a874dc1806..d0d960153f 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8911a8ec35fb8ff3ecb5fc3eec7503ed53d5643c19c2726044ae02569aa374fa -size 69866 +oid sha256:beb5791aeff09f5e757c8f560cc9b705c208eb886462a840bfcab7d78e622c15 +size 69793 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png index e2a8343fef..22917ebb0f 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fa428a419c4693a3bf3039aaaf81968ffbb1d330208170efd60f9e02768f20e -size 60619 +oid sha256:f3285a648f80647c159933a083458fefd4d7f59687b74baacfd4a8dc7296ff05 +size 60504 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_0_de.png index ec8d9ddde3..632d13a773 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b18c02b0e05fe86aca68378a112e698958780e30891c5c0a3e7f316ffd00f657 -size 72919 +oid sha256:6f61101788599662175adfd0b8e3fffa7d0152db1019e8424b2a3011572d1a01 +size 73241 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_10_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_10_de.png index 495d5b4fff..05dae33d65 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_10_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef6a20ea4f3d4b64b294566b242ea8f6021d1a7f54555d6cdbc90f3ed41bf6df -size 56467 +oid sha256:f7d5e0c9b9c13b2e3d1cdfb1cbd666ced079e0faf230febc2377b9e10fab58be +size 56519 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_11_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_11_de.png index 45025e9fb0..2443e232c8 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_11_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eceb56163d5b3a4398fc7711b76b2b09cf98be3006c0f2469011b233cb2751a8 -size 71145 +oid sha256:81030d66c1ddbdf113dd49ea1a566cff5e6591d4733d27925673a99ad2f413f8 +size 71646 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_1_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_1_de.png index 876f0759f5..5b4f8dddd2 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_1_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f88e186b6a2c7bb78a7d0a3244324fb873616f72ab77b7cbe71354671241025 -size 82466 +oid sha256:3c7ef69c814541c026cf01b4466cb10f8737db3f673e81dbb57d1e5e8902f972 +size 83116 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_2_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_2_de.png index a95036ff4a..e6cd15541d 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_2_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:669073bf986640f0602b24c8f203f6272eeb83d57c9fb6e88757364b0bdd55a6 -size 59507 +oid sha256:081a69d09ed70a4bbba08690df9dab86d4a10a980f1330b3b27943cb1c10dff5 +size 59746 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_3_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_3_de.png index 592cf9b318..c8eec3eb85 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_3_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:586b85f5d172f37e9fc0f90317b31826844a6ee598cc1835df72d398e1c57caf -size 58625 +oid sha256:893e712436eafea1791ad4bde6ef16b6e8389ed6dfcf6f5cd206f4e5cb25b44a +size 58863 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_4_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_4_de.png index 256f3f11be..23c18ff2f0 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_4_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f11d0c70af70619812455a42dcf01c9f891f727868c276975003aeb3bf8f97e -size 66007 +oid sha256:72906d598feb20fba5d764485aa54ec3b3eb49ba9574dea5f97fefe8a5519a45 +size 66137 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png index 0fb81544f4..29d057fff0 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:503b031ed7f21cb022b5e1d41ed83baa8998469e5140008f349bd755b2e76416 -size 101507 +oid sha256:fb9602983bbbf519d40a602fd7670585cf376aeb9a72a95e6da4077aae2d340b +size 101576 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_6_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_6_de.png index 8193b57db1..ba9ec7f709 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_6_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26bc4f2e52ed22162d4c8a720f4d0b2793b3d97e45d3463616b3b21b0c4638af -size 57853 +oid sha256:b8e52bb1582b86c3ba756282de449d61c673d7750c35813a712061456f246e4a +size 57799 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_7_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_7_de.png index 92082e6e30..6313c48a1e 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_7_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cca5604149f542ec66a1be21a9ee8220405c49e40e7f974d83d6c60d7133e4bb -size 59690 +oid sha256:9da73f77e0e7aa91c0620b6714dcf81234939f42773ef2afeb6bd920af6d3593 +size 57852 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_8_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_8_de.png index 030c42869a..c115f5a9db 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_8_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4fcd11760900caeb73940f5618b5c33b54827e9e4a25e2f95ebc1e0200b7cd49 -size 68033 +oid sha256:3ae4658c6ce320cf09ca92d8321736d5079e085d7d41791ff33a2811a48fe2da +size 68025 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_9_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_9_de.png index 29186b70be..0b321d53de 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_9_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3be967e3c38366b75f13003171dce8d03886814d9b8663768d28876672f041e5 -size 57219 +oid sha256:0ae8ddc2b5c7794bebb89110d9538c86f9ad90e1edc6df837b1710f19bd13aed +size 57175 diff --git a/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png index 5b616e7a55..98ecbe8286 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6964f7b2f51a7d928d49038d1ed48b4576163c329564e4bd928c32cb9ed6648 -size 55506 +oid sha256:65a53d64c78f99ff6d36f8e6597ba7404a7e27581d823a5674d46459d15a97ca +size 55407 diff --git a/screenshots/de/libraries.textcomposer_TextComposerSimple_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerSimple_Day_0_de.png index 5fce0aa30e..fe5975ff4f 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerSimple_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerSimple_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7636fa5e1fb1ef1e5972f7c973ca0282c87e6624fb150abd7f9198083c39fc29 -size 43642 +oid sha256:ea1736c6617804eb12450189db18dec3d1959b2d426aeb298c6164609f23319c +size 43565 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 62bb50771b..1ecfab0491 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,87 +1,87 @@ // 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",20532,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20539,], ["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",20532,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20532,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20532,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20532,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20532,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20532,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20532,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20532,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20532,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20532,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20532,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20539,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20539,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20539,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20539,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20539,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20539,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20539,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20539,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20539,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20539,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20539,], ["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",20532,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20532,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20539,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20539,], ["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",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20532,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20539,], ["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",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20532,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20532,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20532,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20532,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20532,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_0_en","features.space.impl.addroom_AddRoomToSpaceView_Night_0_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_1_en","features.space.impl.addroom_AddRoomToSpaceView_Night_1_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_2_en","features.space.impl.addroom_AddRoomToSpaceView_Night_2_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_3_en","features.space.impl.addroom_AddRoomToSpaceView_Night_3_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_4_en","features.space.impl.addroom_AddRoomToSpaceView_Night_4_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_5_en","features.space.impl.addroom_AddRoomToSpaceView_Night_5_en",20532,], -["features.space.impl.addroom_AddRoomToSpaceView_Day_6_en","features.space.impl.addroom_AddRoomToSpaceView_Night_6_en",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20532,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20532,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20532,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20532,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20539,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20539,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20539,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20539,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20539,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_0_en","features.space.impl.addroom_AddRoomToSpaceView_Night_0_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_1_en","features.space.impl.addroom_AddRoomToSpaceView_Night_1_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_2_en","features.space.impl.addroom_AddRoomToSpaceView_Night_2_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_3_en","features.space.impl.addroom_AddRoomToSpaceView_Night_3_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_4_en","features.space.impl.addroom_AddRoomToSpaceView_Night_4_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_5_en","features.space.impl.addroom_AddRoomToSpaceView_Night_5_en",20539,], +["features.space.impl.addroom_AddRoomToSpaceView_Day_6_en","features.space.impl.addroom_AddRoomToSpaceView_Night_6_en",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20539,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20539,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20539,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20539,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20532,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20532,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20532,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20532,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20532,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20539,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20539,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20539,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20539,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20539,], ["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",20532,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20539,], ["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",20532,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20539,], ["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",20532,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20539,], ["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",20532,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20539,], ["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",20532,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20539,], ["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,], @@ -91,19 +91,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_AttachmentsPreviewView_0_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20532,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20532,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20539,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20539,], ["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",20532,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20539,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en","libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en",0,], ["libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en","libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en",0,], @@ -133,22 +133,22 @@ export const screenshots = [ ["libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_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",20532,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20539,], ["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",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20532,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20532,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20539,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20539,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20532,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20532,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20532,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20532,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20532,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20539,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20539,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20539,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20539,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20539,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -159,141 +159,141 @@ export const screenshots = [ ["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",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20532,], -["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",20532,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20539,], +["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",20539,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_6_en","features.messages.impl.timeline.components_CallMenuItem_Night_6_en",20532,], +["features.messages.impl.timeline.components_CallMenuItem_Day_6_en","features.messages.impl.timeline.components_CallMenuItem_Night_6_en",20539,], ["features.messages.impl.timeline.components_CallMenuItem_Day_7_en","features.messages.impl.timeline.components_CallMenuItem_Night_7_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",20532,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20532,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20532,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20532,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20532,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20532,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20539,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20539,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20539,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20539,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20539,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20539,], ["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en",0,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20532,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20532,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",20532,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20539,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20539,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",20539,], ["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",20532,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20532,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20532,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20532,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20532,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20539,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20539,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20539,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20539,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20539,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20532,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20539,], ["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",20532,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20532,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20532,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20532,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20532,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20532,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20532,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20532,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20539,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20539,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20539,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20539,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20539,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20539,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20539,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20539,], ["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",20532,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20532,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20532,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20532,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20532,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20532,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20532,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20539,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20539,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20539,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20539,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20539,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20539,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20539,], ["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","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en","",20532,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en","",20532,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20532,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20532,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20532,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20532,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_7_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_8_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_7_en","",20539,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_8_en","",20539,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20539,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20539,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20539,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20539,], ["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_ConnectivityIndicator_Day_0_en","features.networkmonitor.api.ui_ConnectivityIndicator_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",20532,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20532,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20532,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20532,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20532,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20532,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20532,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20532,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20532,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20532,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20532,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20532,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20532,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20532,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20532,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20532,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20532,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20532,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20532,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20532,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20539,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20539,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20539,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20539,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20539,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20539,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20539,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20539,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20539,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20539,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20539,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20539,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20539,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20539,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20539,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20539,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20539,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20539,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20539,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20539,], ["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","",20532,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20532,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20532,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20532,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20532,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20532,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20532,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20539,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20539,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20539,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20539,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20539,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20539,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20539,], ["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",20532,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20532,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20532,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20539,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20539,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20539,], ["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",20532,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20539,], ["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",20532,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20532,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20532,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20532,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20532,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20532,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20532,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20532,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20532,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20532,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20539,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20539,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20539,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20539,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20539,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20539,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20539,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20539,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20539,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20539,], ["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,], @@ -308,19 +308,19 @@ 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",20532,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20532,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20532,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20532,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20532,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20532,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20532,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20532,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20532,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20532,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20532,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20532,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20532,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20539,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20539,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20539,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20539,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20539,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20539,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20539,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20539,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20539,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20539,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20539,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20539,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20539,], ["libraries.matrix.ui.components_EditableOrgAvatarRtl_Day_0_en","libraries.matrix.ui.components_EditableOrgAvatarRtl_Night_0_en",0,], ["libraries.matrix.ui.components_EditableOrgAvatar_Day_0_en","libraries.matrix.ui.components_EditableOrgAvatar_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomLargeNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomLargeNoBlurShadow_Night_0_en",0,], @@ -328,28 +328,28 @@ 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",20532,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20532,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20539,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20539,], ["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.ui.common.nodes_EmptyView_Day_0_en","libraries.ui.common.nodes_EmptyView_Night_0_en",0,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20532,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20532,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20532,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20532,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20532,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20532,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20532,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20532,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20532,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20532,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20539,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20539,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20539,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20539,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20539,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20539,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20539,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20539,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20539,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20539,], ["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,], @@ -368,48 +368,48 @@ 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",20532,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20532,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20532,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20539,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20539,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20539,], ["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.forward.impl_ForwardMessagesView_Day_0_en","features.forward.impl_ForwardMessagesView_Night_0_en",0,], ["features.forward.impl_ForwardMessagesView_Day_1_en","features.forward.impl_ForwardMessagesView_Night_1_en",0,], ["features.forward.impl_ForwardMessagesView_Day_2_en","features.forward.impl_ForwardMessagesView_Night_2_en",0,], -["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20532,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20532,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20539,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20539,], ["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",20532,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20532,], -["features.home.impl.spaces_HomeSpacesView_Day_2_en","features.home.impl.spaces_HomeSpacesView_Night_2_en",20532,], -["features.home.impl.spaces_HomeSpacesView_Day_3_en","features.home.impl.spaces_HomeSpacesView_Night_3_en",20532,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20532,], -["features.home.impl.components_HomeTopBarSpaceFiltersSelected_Day_0_en","features.home.impl.components_HomeTopBarSpaceFiltersSelected_Night_0_en",20532,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20539,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20539,], +["features.home.impl.spaces_HomeSpacesView_Day_2_en","features.home.impl.spaces_HomeSpacesView_Night_2_en",20539,], +["features.home.impl.spaces_HomeSpacesView_Day_3_en","features.home.impl.spaces_HomeSpacesView_Night_3_en",20539,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20539,], +["features.home.impl.components_HomeTopBarSpaceFiltersSelected_Day_0_en","features.home.impl.components_HomeTopBarSpaceFiltersSelected_Night_0_en",20539,], ["features.home.impl.components_HomeTopBarSpaces_Day_0_en","features.home.impl.components_HomeTopBarSpaces_Night_0_en",0,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20532,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20532,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20539,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20539,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20532,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20532,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20539,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20539,], ["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",20532,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20532,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20532,], -["features.home.impl_HomeView_Day_16_en","features.home.impl_HomeView_Night_16_en",20532,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20532,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20532,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20532,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20532,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20532,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20532,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20532,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20532,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20532,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20539,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20539,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20539,], +["features.home.impl_HomeView_Day_16_en","features.home.impl_HomeView_Night_16_en",20539,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20539,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20539,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20539,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20539,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20539,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20539,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20539,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20539,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20539,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.theme.components_HorizontalFloatingToolbarNoFab_Day_0_en","libraries.designsystem.theme.components_HorizontalFloatingToolbarNoFab_Night_0_en",0,], ["libraries.designsystem.theme.components_HorizontalFloatingToolbar_Day_0_en","libraries.designsystem.theme.components_HorizontalFloatingToolbar_Night_0_en",0,], @@ -424,8 +424,8 @@ export const screenshots = [ ["appicon.enterprise_Icon_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",20532,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20532,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20539,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20539,], ["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,], @@ -433,117 +433,117 @@ 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",20532,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20539,], ["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",20532,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20539,], ["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",20532,], -["features.call.impl.ui_IncomingCallScreen_Day_1_en","features.call.impl.ui_IncomingCallScreen_Night_1_en",20532,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20539,], +["features.call.impl.ui_IncomingCallScreen_Day_1_en","features.call.impl.ui_IncomingCallScreen_Night_1_en",20539,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20532,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20532,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20539,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20539,], ["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",20532,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20532,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20532,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20539,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20539,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20539,], ["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",20532,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20532,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20532,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20532,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20539,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20539,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20539,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20539,], ["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",20532,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20532,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20532,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20539,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20539,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20539,], ["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",20532,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20532,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20532,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20532,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20532,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20539,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20539,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20539,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20539,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20532,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20532,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20539,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20539,], ["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",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20532,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_10_en","features.space.impl.leave_LeaveSpaceView_Night_10_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20532,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20532,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20539,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_10_en","features.space.impl.leave_LeaveSpaceView_Night_10_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20539,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20539,], ["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.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en",20532,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",20532,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20532,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20532,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",20532,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20532,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en",20539,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",20539,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20539,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20539,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",20539,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20539,], ["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",20532,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20539,], ["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,], @@ -598,41 +598,43 @@ 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",20532,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20532,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20532,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20532,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20539,], +["libraries.designsystem.components_LocationPin_Day_0_en","libraries.designsystem.components_LocationPin_Night_0_en",0,], +["features.location.impl.common.ui_LocationShareRow_Day_0_en","features.location.impl.common.ui_LocationShareRow_Night_0_en",0,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20539,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20539,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20539,], ["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",20532,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20532,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20532,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20532,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20532,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20532,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20532,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20532,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20532,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20532,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20532,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20532,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20532,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20532,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20532,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20532,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20532,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20532,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20532,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20532,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20532,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20532,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20532,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20532,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20532,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20539,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20539,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20539,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20539,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20539,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20539,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20539,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20539,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20539,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20539,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20539,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20539,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20539,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20539,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20539,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20539,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20539,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20539,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20539,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20539,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20539,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20539,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20539,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20539,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20539,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en",20532,], -["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en",20532,], -["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en",20532,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20532,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en",20539,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en",20539,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en",20539,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20539,], ["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,], @@ -646,22 +648,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",20532,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20532,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20539,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20539,], ["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",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20532,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20532,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20539,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20539,], ["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,], @@ -669,14 +671,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","",20532,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20532,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20539,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20539,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20532,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20539,], ["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","",20532,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20539,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -690,7 +692,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",20532,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20539,], ["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,], @@ -699,7 +701,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",20532,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20539,], ["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,], @@ -708,23 +710,23 @@ export const screenshots = [ ["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_MessagesViewA11y_en","",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20532,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20532,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20532,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20532,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20532,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20532,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20532,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20532,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20532,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20532,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20532,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20532,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20532,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20532,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20532,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20539,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20539,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20539,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20539,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20539,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20539,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20539,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20539,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20539,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20539,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20539,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20539,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20539,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20539,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20539,], ["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",20532,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20539,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], @@ -735,113 +737,112 @@ export const screenshots = [ ["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.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20532,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20532,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20532,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20539,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20539,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20539,], ["features.linknewdevice.impl.screens.number.component_NumberTextField_Day_0_en","features.linknewdevice.impl.screens.number.component_NumberTextField_Night_0_en",0,], ["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",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20532,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20532,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20539,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20539,], ["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",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20532,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20539,], ["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",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20532,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20532,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20539,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20539,], ["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",20532,], -["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20532,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20532,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20532,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20532,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20532,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20539,], +["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20539,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20539,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20539,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20539,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20539,], ["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",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20532,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20532,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20539,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20539,], ["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",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20532,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20532,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20532,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20532,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20532,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20532,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20539,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20539,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20539,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20539,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20539,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20539,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en","libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20532,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20532,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20532,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20532,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20532,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20539,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20539,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20539,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20539,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20539,], ["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",20532,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20532,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20532,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20532,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20532,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20532,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20532,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20532,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20532,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20532,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20532,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20539,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20539,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20539,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20539,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20539,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20539,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20539,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20539,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20539,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20539,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20539,], ["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,], @@ -855,215 +856,215 @@ 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","",20532,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20532,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20532,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20532,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20539,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20539,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20539,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20539,], ["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","",20532,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20532,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20539,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20532,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20532,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20532,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20532,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20532,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20532,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20532,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20532,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20532,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20532,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20532,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20532,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20532,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20532,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20532,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20539,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20539,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20539,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20539,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20539,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20539,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20539,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20539,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20539,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20539,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20539,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20539,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20539,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20539,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20539,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20539,], ["libraries.qrcode_QrCodeView_en","",0,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20532,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20532,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20539,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20532,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20532,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20532,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20532,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20532,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20532,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20539,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20539,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20539,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20539,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20539,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20539,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20539,], ["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",20532,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20532,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20532,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20532,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20532,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20532,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20532,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20532,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20532,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20532,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20532,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20532,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20532,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20532,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20532,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20532,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20532,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20539,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20539,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20539,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20539,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20539,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20539,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20539,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20539,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20539,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20539,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20539,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20539,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20539,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20539,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20539,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20539,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20539,], ["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",20532,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20532,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20532,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20532,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20532,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20539,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20539,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20539,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20539,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20539,], ["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",20532,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20532,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20539,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20539,], ["features.roomdetails.impl_RoomDetailsA11y_en","",0,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_20_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_21_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_22_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20532,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20532,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20532,], -["features.roomdetails.impl_RoomDetails_0_en","",20532,], -["features.roomdetails.impl_RoomDetails_10_en","",20532,], -["features.roomdetails.impl_RoomDetails_11_en","",20532,], -["features.roomdetails.impl_RoomDetails_12_en","",20532,], -["features.roomdetails.impl_RoomDetails_13_en","",20532,], -["features.roomdetails.impl_RoomDetails_14_en","",20532,], -["features.roomdetails.impl_RoomDetails_15_en","",20532,], -["features.roomdetails.impl_RoomDetails_16_en","",20532,], -["features.roomdetails.impl_RoomDetails_17_en","",20532,], -["features.roomdetails.impl_RoomDetails_18_en","",20532,], -["features.roomdetails.impl_RoomDetails_19_en","",20532,], -["features.roomdetails.impl_RoomDetails_1_en","",20532,], -["features.roomdetails.impl_RoomDetails_20_en","",20532,], -["features.roomdetails.impl_RoomDetails_21_en","",20532,], -["features.roomdetails.impl_RoomDetails_22_en","",20532,], -["features.roomdetails.impl_RoomDetails_2_en","",20532,], -["features.roomdetails.impl_RoomDetails_3_en","",20532,], -["features.roomdetails.impl_RoomDetails_4_en","",20532,], -["features.roomdetails.impl_RoomDetails_5_en","",20532,], -["features.roomdetails.impl_RoomDetails_6_en","",20532,], -["features.roomdetails.impl_RoomDetails_7_en","",20532,], -["features.roomdetails.impl_RoomDetails_8_en","",20532,], -["features.roomdetails.impl_RoomDetails_9_en","",20532,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20532,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20532,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20532,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20532,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20532,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20532,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20532,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20532,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20532,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_20_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_21_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_22_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20539,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20539,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20539,], +["features.roomdetails.impl_RoomDetails_0_en","",20539,], +["features.roomdetails.impl_RoomDetails_10_en","",20539,], +["features.roomdetails.impl_RoomDetails_11_en","",20539,], +["features.roomdetails.impl_RoomDetails_12_en","",20539,], +["features.roomdetails.impl_RoomDetails_13_en","",20539,], +["features.roomdetails.impl_RoomDetails_14_en","",20539,], +["features.roomdetails.impl_RoomDetails_15_en","",20539,], +["features.roomdetails.impl_RoomDetails_16_en","",20539,], +["features.roomdetails.impl_RoomDetails_17_en","",20539,], +["features.roomdetails.impl_RoomDetails_18_en","",20539,], +["features.roomdetails.impl_RoomDetails_19_en","",20539,], +["features.roomdetails.impl_RoomDetails_1_en","",20539,], +["features.roomdetails.impl_RoomDetails_20_en","",20539,], +["features.roomdetails.impl_RoomDetails_21_en","",20539,], +["features.roomdetails.impl_RoomDetails_22_en","",20539,], +["features.roomdetails.impl_RoomDetails_2_en","",20539,], +["features.roomdetails.impl_RoomDetails_3_en","",20539,], +["features.roomdetails.impl_RoomDetails_4_en","",20539,], +["features.roomdetails.impl_RoomDetails_5_en","",20539,], +["features.roomdetails.impl_RoomDetails_6_en","",20539,], +["features.roomdetails.impl_RoomDetails_7_en","",20539,], +["features.roomdetails.impl_RoomDetails_8_en","",20539,], +["features.roomdetails.impl_RoomDetails_9_en","",20539,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20539,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20539,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20539,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20539,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20539,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20539,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20539,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20539,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20539,], ["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",20532,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20532,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20532,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20532,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20532,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20532,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20532,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20532,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20532,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20539,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20539,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20539,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20539,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20539,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20539,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20539,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20539,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20539,], ["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",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20532,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20532,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20532,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20539,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20539,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20539,], ["features.roommembermoderation.impl_RoomMemberModerationView_Day_9_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_9_en",0,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20532,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20532,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20539,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20539,], ["libraries.designsystem.atomic.atoms_RoomPreviewAliasAtom_Day_0_en","libraries.designsystem.atomic.atoms_RoomPreviewAliasAtom_Night_0_en",0,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20532,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20532,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20532,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20532,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20532,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20532,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20539,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20539,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20539,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20539,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20539,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20539,], ["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,], @@ -1086,16 +1087,16 @@ 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",20532,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20532,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20532,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20539,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20539,], ["features.home.impl.components_RoomSummaryRow_Day_36_en","features.home.impl.components_RoomSummaryRow_Night_36_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_37_en","features.home.impl.components_RoomSummaryRow_Night_37_en",20532,], +["features.home.impl.components_RoomSummaryRow_Day_37_en","features.home.impl.components_RoomSummaryRow_Night_37_en",20539,], ["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,], @@ -1103,118 +1104,118 @@ 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",20532,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20532,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20532,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20539,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20539,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20539,], ["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",20532,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20532,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20532,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20532,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20532,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20532,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20532,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20532,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20539,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20539,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20539,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20539,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20539,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20539,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20539,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20539,], ["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","",20532,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20539,], ["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,], ["libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en","",0,], -["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20532,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20532,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20532,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20532,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20532,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20532,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20532,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20532,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20532,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20532,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20532,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20532,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20532,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20532,], -["features.createroom.impl.configureroom_SelectParentSpaceBottomSheet_Day_0_en","features.createroom.impl.configureroom_SelectParentSpaceBottomSheet_Night_0_en",20532,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20539,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20539,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20539,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20539,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20539,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20539,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20539,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20539,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20539,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20539,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20539,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20539,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20539,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20539,], +["features.createroom.impl.configureroom_SelectParentSpaceBottomSheet_Day_0_en","features.createroom.impl.configureroom_SelectParentSpaceBottomSheet_Night_0_en",20539,], ["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,], @@ -1228,11 +1229,6 @@ 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_SendButtonIcon_Day_0_en","libraries.textcomposer.components_SendButtonIcon_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20532,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20532,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20532,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20532,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20532,], ["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,], @@ -1242,28 +1238,33 @@ 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",20532,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20532,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20532,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20532,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20532,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20532,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20532,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20532,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20539,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20539,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20539,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20539,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20539,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20539,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20539,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20539,], +["features.location.impl.share_ShareLocationView_Day_0_en","features.location.impl.share_ShareLocationView_Night_0_en",20542,], +["features.location.impl.share_ShareLocationView_Day_1_en","features.location.impl.share_ShareLocationView_Night_1_en",20542,], +["features.location.impl.share_ShareLocationView_Day_2_en","features.location.impl.share_ShareLocationView_Night_2_en",20542,], +["features.location.impl.share_ShareLocationView_Day_3_en","features.location.impl.share_ShareLocationView_Night_3_en",20542,], +["features.location.impl.share_ShareLocationView_Day_4_en","features.location.impl.share_ShareLocationView_Night_4_en",20542,], +["features.location.impl.share_ShareLocationView_Day_5_en","features.location.impl.share_ShareLocationView_Night_5_en",20542,], +["features.location.impl.share_ShareLocationView_Day_6_en","features.location.impl.share_ShareLocationView_Night_6_en",20542,], ["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",20532,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20532,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20532,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20532,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20532,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20532,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20532,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20532,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20532,], -["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20532,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20532,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20539,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20539,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20539,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20539,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20539,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20539,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20539,], +["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20539,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20539,], ["libraries.designsystem.components_SimpleModalBottomSheet_Day_0_en","libraries.designsystem.components_SimpleModalBottomSheet_Night_0_en",0,], ["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,], @@ -1273,107 +1274,107 @@ 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",20532,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20539,], ["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",20532,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20539,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["features.home.impl.spacefilters_SpaceFiltersView_Day_0_en","features.home.impl.spacefilters_SpaceFiltersView_Night_0_en",20532,], -["features.home.impl.spacefilters_SpaceFiltersView_Day_1_en","features.home.impl.spacefilters_SpaceFiltersView_Night_1_en",20532,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20532,], +["features.home.impl.spacefilters_SpaceFiltersView_Day_0_en","features.home.impl.spacefilters_SpaceFiltersView_Night_0_en",20539,], +["features.home.impl.spacefilters_SpaceFiltersView_Day_1_en","features.home.impl.spacefilters_SpaceFiltersView_Night_1_en",20539,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20539,], ["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",0,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20532,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20539,], ["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",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20532,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20532,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20532,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20532,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20532,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20532,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20532,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20532,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20532,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20532,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20532,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20532,], -["features.space.impl.root_SpaceView_Day_6_en","features.space.impl.root_SpaceView_Night_6_en",20532,], -["features.space.impl.root_SpaceView_Day_7_en","features.space.impl.root_SpaceView_Night_7_en",20532,], -["features.space.impl.root_SpaceView_Day_8_en","features.space.impl.root_SpaceView_Night_8_en",20532,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20539,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20539,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20539,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20539,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20539,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20539,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20539,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20539,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20539,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20539,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20539,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20539,], +["features.space.impl.root_SpaceView_Day_6_en","features.space.impl.root_SpaceView_Night_6_en",20539,], +["features.space.impl.root_SpaceView_Day_7_en","features.space.impl.root_SpaceView_Night_7_en",20539,], +["features.space.impl.root_SpaceView_Day_8_en","features.space.impl.root_SpaceView_Night_8_en",20539,], ["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",20532,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20532,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20532,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20532,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20532,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20532,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20532,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20539,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20539,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20539,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20539,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20539,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20539,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20539,], ["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",20532,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20539,], ["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",20532,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20539,], ["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",20532,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20532,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20532,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20532,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20532,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20532,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20532,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20532,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20532,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20532,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20532,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20532,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20532,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20532,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20532,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20539,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20539,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20539,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20539,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20539,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20539,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20539,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20539,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20539,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20539,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20539,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20539,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20539,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20539,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20539,], ["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",20532,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20532,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20539,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20539,], ["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,], @@ -1385,16 +1386,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",20532,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20532,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20532,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20532,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20532,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20539,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20539,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20539,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20539,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20539,], ["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",20532,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20532,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20539,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20539,], ["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,], @@ -1404,18 +1405,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",20532,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20532,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20539,], ["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,], @@ -1423,18 +1424,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",20532,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20539,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20532,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20539,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20539,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20539,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20539,], ["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,], @@ -1443,41 +1444,42 @@ 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",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20539,], ["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",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20539,], ["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",20532,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20539,], ["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","",20532,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20539,], ["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",20532,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20532,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20539,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20539,], ["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",20532,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20532,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20532,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20532,], +["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_2_en",0,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20539,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20539,], ["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",20532,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20532,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20539,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20539,], ["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",20532,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20539,], ["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,], @@ -1486,8 +1488,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",20532,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20532,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20539,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20539,], ["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,], @@ -1502,8 +1504,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",20532,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20532,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20539,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20539,], ["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,], @@ -1526,85 +1528,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",20532,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20532,], -["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",20532,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20532,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20532,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_10_en","features.messages.impl.timeline_TimelineView_Night_10_en",20542,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20539,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",0,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20539,], ["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",20532,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20539,], ["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",20532,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20539,], ["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",0,], ["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",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20532,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20532,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20539,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20539,], ["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",20532,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20532,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20532,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20532,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20532,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20532,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20539,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20539,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20539,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20539,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20539,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20539,], ["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","",20532,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20539,], ["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",20532,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20532,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20532,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20532,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20539,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20539,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20539,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20539,], ["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",20532,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20539,], ["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",20532,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20539,], ["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",20532,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20532,], -["features.userprofile.shared_UserProfileMainActionsSection_Day_0_en","features.userprofile.shared_UserProfileMainActionsSection_Night_0_en",20532,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20532,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20532,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20532,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20532,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20532,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20532,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20532,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20532,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20532,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20532,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20539,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20539,], +["features.userprofile.shared_UserProfileMainActionsSection_Day_0_en","features.userprofile.shared_UserProfileMainActionsSection_Night_0_en",20539,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20539,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20539,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20539,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20539,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20539,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20539,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20539,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20539,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20539,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20539,], ["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.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20532,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20532,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20539,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20539,], ["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",20532,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20539,], ["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,], diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png index 8dda833412..fcc2640262 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f3df9c9de000b15692b982c7d69f85ce3d03cab468c342773c88eff3b4fca65 -size 9082 +oid sha256:4d8c17c2e421452f57e4679111569054e1ed1bacc952cc1df4c7efe1f67c47ef +size 13158 From cb4c7cdb378132c1c892665db8036a6e8601b554 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:49:20 +0200 Subject: [PATCH 095/103] fix(deps): update dependency com.google.crypto.tink:tink-android to v1.21.0 (#6499) 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 86db5a9d73..3f16060207 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -84,7 +84,7 @@ google_firebase_bom = "com.google.firebase:firebase-bom:34.11.0" firebase_appdistribution_gradle = { module = "com.google.firebase:firebase-appdistribution-gradle", version.ref = "firebaseAppDistribution" } autonomousapps_dependencyanalysis_plugin = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysis" } ksp_plugin = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } -google_tink = "com.google.crypto.tink:tink-android:1.20.0" +google_tink = "com.google.crypto.tink:tink-android:1.21.0" # AndroidX androidx_core = { module = "androidx.core:core", version.ref = "core" } From dbd51ebc9012686db954bf91555a9eec1edef8e1 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 31 Mar 2026 16:57:37 +0200 Subject: [PATCH 096/103] Try fixing location pin previews (#6495) * Try fixing location pin previews * Update screenshots --------- Co-authored-by: ElementBot Co-authored-by: Benoit Marty --- .../designsystem/components/LocationPin.kt | 57 ++++++++++++------- ....impl.share_ShareLocationView_Day_5_en.png | 4 +- ...mpl.share_ShareLocationView_Night_5_en.png | 4 +- ...system.components_LocationPin_Day_0_en.png | 4 +- ...stem.components_LocationPin_Night_0_en.png | 4 +- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt index af8e29d518..9e783d605c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt @@ -32,9 +32,13 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp +import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.createBitmap +import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.withSave import coil3.Image import coil3.ImageLoader @@ -50,6 +54,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.utils.CommonDrawables private val PIN_WIDTH = 42.dp private val PIN_HEIGHT = PIN_WIDTH * 1.2f @@ -99,21 +104,33 @@ fun LocationPin( fun rememberLocationPinBitmap(variant: PinVariant): ImageBitmap? { val context = LocalContext.current val density = LocalDensity.current - val imageLoader = SingletonImageLoader.get(context) val colors = pinColors(variant) val cacheKey = rememberCacheKey(variant) - return produceState(initialValue = null, cacheKey) { - val memoryCacheKey = MemoryCache.Key(cacheKey) - val cached = imageLoader.memoryCache?.get(memoryCacheKey) - if (cached != null) { - value = cached.image.toBitmap().asImageBitmap() - } else { - val dimensions = PinDimensions(density) - val bitmap = LocationPinRenderer.renderPin(variant, colors, dimensions, context, imageLoader) - imageLoader.memoryCache?.set(memoryCacheKey, MemoryCache.Value(bitmap.asImage())) - value = bitmap.asImageBitmap() - } - }.value + val resources = LocalResources.current + + return if (LocalInspectionMode.current) { + // In preview mode, skip async loading and return a simple placeholder image instead to avoid using ImageLoader + val dimensions = PinDimensions(density) + val avatarImage = ResourcesCompat.getDrawable(resources, CommonDrawables.sample_avatar, context.theme)?.toBitmap()?.asImage() + LocationPinRenderer.renderPin(variant, colors, dimensions, avatarImage).asImageBitmap() + } else { + produceState(initialValue = null, cacheKey) { + val imageLoader = SingletonImageLoader.get(context) + val memoryCacheKey = MemoryCache.Key(cacheKey) + val cached = imageLoader.memoryCache?.get(memoryCacheKey) + if (cached != null) { + value = cached.image.toBitmap().asImageBitmap() + } else { + val dimensions = PinDimensions(density) + val bitmap = with(LocationPinRenderer) { + val avatarImage = loadAvatarImage(variant, context, imageLoader) + renderPin(variant, colors, dimensions, avatarImage) + } + imageLoader.memoryCache?.set(memoryCacheKey, MemoryCache.Value(bitmap.asImage())) + value = bitmap.asImageBitmap() + } + }.value + } } @Composable @@ -208,19 +225,17 @@ private object LocationPinRenderer { /** * Renders a pin variant to bitmap. Suspending for async avatar loading. */ - suspend fun renderPin( + fun renderPin( variant: PinVariant, colors: PinColors, dimensions: PinDimensions, - context: Context, - imageLoader: ImageLoader, + avatarImage: Image?, ): Bitmap { val bitmap = createBitmap(dimensions.pinWidth.toInt(), dimensions.pinHeight.toInt()) val canvas = Canvas(bitmap) canvas.drawPinShape(colors.fill, colors.stroke, dimensions) when (variant) { is PinVariant.UserLocation -> { - val avatarImage = loadAvatarImage(variant.avatarData, context, imageLoader) canvas.drawAvatar( avatarImage = avatarImage, avatarData = variant.avatarData, @@ -284,11 +299,15 @@ private object LocationPinRenderer { return path } - private suspend fun loadAvatarImage( - avatarData: AvatarData, + suspend fun loadAvatarImage( + variant: PinVariant, context: Context, imageLoader: ImageLoader, ): Image? { + val avatarData = when (variant) { + is PinVariant.UserLocation -> variant.avatarData + else -> return null + } val request = ImageRequest.Builder(context) .data(avatarData) // Disable hardware rendering for Canvas diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png index 69aea3df2a..74d6ac15ca 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ba1418b5d42a56db47e7cc574cedb886c75d9cf22828341bd954a4f1845670e -size 17925 +oid sha256:2621fef4175ad0f0982270284ffbbdb6b3b0534b09013c1cc378504a85d13068 +size 22385 diff --git a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png index 060f25819e..d79bfca142 100644 --- a/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.location.impl.share_ShareLocationView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d786937d790e13b53a5de8ae3321e5aa8744a979a3a99ecc36def6b7dbf6cf60 -size 17237 +oid sha256:69bcf19161f70c27256c1bf0e5b99c993c86dd3e77a42d0e87061730a5c0c752 +size 21649 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png index fcc2640262..c049cff102 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d8c17c2e421452f57e4679111569054e1ed1bacc952cc1df4c7efe1f67c47ef -size 13158 +oid sha256:ca6415ca7f858146a4c00e2fa1d9602fd9f3d42c0c8ba9830e121769af80676a +size 17255 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png index dac3588ed9..8074748111 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_LocationPin_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9767298a096be7fc78210245e6b806a72a6c1ad16d7335e0f89728bbcf08ebd4 -size 15884 +oid sha256:d89b754907f98ef1df2cf227ec535cdad91dc15e90b4915039be39d8b2ae2ebd +size 16721 From 786c260fc29fb26415fcdcf5fdb173ec73bf23a8 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 31 Mar 2026 18:45:10 +0200 Subject: [PATCH 097/103] Fix crash when using `View.hideKeyboardAndAwaitAnimation` (#6502) * Fix crash when using `View.hideKeyboardAndAwaitAnimation` Remove the `View.OnApplyWindowInsetsListener` used in modern Android versions to detect if the insets changed after they do the first time: this is a single use operation and the listener will be called every time the insets change Also, replace `Mutex` with `CompletableDeferred` so it doesn't matter if it's called several times, we only care about the first one. * Don't try to hide the keyboard if it's already hidden. Also, add a 1s timeout in case everything goes wrong and we somehow never complete the future. --- .../android/libraries/androidutils/ui/View.kt | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/ui/View.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/ui/View.kt index ae724a7c44..5f19cba136 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/ui/View.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/ui/View.kt @@ -16,9 +16,11 @@ import android.view.ViewTreeObserver import android.view.WindowInsets import android.view.inputmethod.InputMethodManager import androidx.core.content.getSystemService +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.suspendCancellableCoroutine -import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.withTimeoutOrNull import kotlin.coroutines.resume +import kotlin.time.Duration.Companion.seconds fun View.hideKeyboard() { val imm = context?.getSystemService() @@ -26,29 +28,39 @@ fun View.hideKeyboard() { } suspend fun View.hideKeyboardAndAwaitAnimation() { - val imm = context?.getSystemService() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !rootWindowInsets.isVisible(WindowInsets.Type.ime())) { + // Keyboard is already hidden, no need to do anything + return + } - val mutex = Mutex() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val imm = context?.getSystemService() ?: return + val future = CompletableDeferred() + + val requested = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { setOnApplyWindowInsetsListener { view, insets -> if (!insets.isVisible(WindowInsets.Type.ime())) { - mutex.unlock() + future.complete(Unit) + // Remove the listener now, it's a single use operation + setOnApplyWindowInsetsListener(null) } insets } - imm?.hideSoftInputFromWindow(windowToken, 0) + imm.hideSoftInputFromWindow(windowToken, 0) } else { @Suppress("DEPRECATION") - imm?.hideSoftInputFromWindow(windowToken, 0, object : ResultReceiver(null) { + imm.hideSoftInputFromWindow(windowToken, 0, object : ResultReceiver(null) { override fun onReceiveResult(resultCode: Int, resultData: Bundle?) { - if (resultCode == InputMethodManager.RESULT_UNCHANGED_HIDDEN || - resultCode == InputMethodManager.RESULT_HIDDEN) { - mutex.unlock() + if (resultCode == InputMethodManager.RESULT_UNCHANGED_HIDDEN || resultCode == InputMethodManager.RESULT_HIDDEN) { + future.complete(Unit) } } }) } - mutex.lock() + + if (requested) { + // Await the future to ensure the keyboard hide animation has completed before proceeding + withTimeoutOrNull(1.seconds) { future.await() } + } } fun View.showKeyboard(andRequestFocus: Boolean = false) { From ba81e44052be1a237332820c2125956f21a3d203 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 1 Apr 2026 11:06:28 +0200 Subject: [PATCH 098/103] Fix content scrolling not working in the RTE (#6492) Implement a `customDetectVerticalDragGestures` that matches the original `detectVerticalDragGestures` expect we conditionally consume the initial DOWN event in compose to decide whether we need to drag the bottom sheet or scroll inside the Android `EditText` --- .../components/ExpandableBottomSheetLayout.kt | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayout.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayout.kt index 85307823f6..f70ed3b344 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayout.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayout.kt @@ -16,7 +16,10 @@ import android.widget.EditText import androidx.appcompat.app.ActionBar.LayoutParams import androidx.compose.animation.core.Animatable import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectVerticalDragGestures +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.foundation.gestures.awaitVerticalPointerSlopOrCancellation +import androidx.compose.foundation.gestures.verticalDrag import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column @@ -41,10 +44,14 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.input.pointer.PointerInputChange +import androidx.compose.ui.input.pointer.PointerInputScope import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.input.pointer.positionChange import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview @@ -94,7 +101,7 @@ fun ExpandableBottomSheetLayout( .run { if (isSwipeGestureEnabled) { pointerInput(maxBottomSheetContentHeight) { - detectVerticalDragGestures( + customDetectVerticalDragGestures( onVerticalDrag = { _, dragAmount -> val calculatedHeight = max(minBottomContentHeightPx, currentBottomContentHeightPx - dragAmount.roundToInt()) val newHeight = min(calculatedMaxBottomContentHeightPx, calculatedHeight) @@ -120,7 +127,11 @@ fun ExpandableBottomSheetLayout( animatable.animateTo(destination) } - } + }, + canScroll = { + // We only consider we can scroll in the contents if the min size matches the max size so it's maximized + minBottomContentHeightPx == calculatedMaxBottomContentHeightPx + }, ) } } else { @@ -189,6 +200,45 @@ fun ExpandableBottomSheetLayout( ) } +// The original detectVerticalDragGestures doesn't allow us to conditionally consume the initial slop event that triggers the drag, +// which is necessary in our case to allow inner scrollables to work when the sheet is not fully expanded, so we need to re-implement it here +private suspend fun PointerInputScope.customDetectVerticalDragGestures( + onDragStart: (Offset) -> Unit = {}, + onDragEnd: () -> Unit = {}, + onDragCancel: () -> Unit = {}, + canScroll: () -> Boolean = { false }, + onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit, +) { + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false) + var overSlop = 0f + val drag = + awaitVerticalPointerSlopOrCancellation(down.id, down.type) { change, over -> + // Consuming this event is what triggers the dragging instead of the inner content scrolling + // We should only consume it if we can't scroll in the inner content so we drag the bottom sheet instead, otherwise we let it pass through + // This is the only change compared to the original detectVerticalDragGestures implementation + if (!canScroll()) { + change.consume() + } + overSlop = over + } + if (drag != null) { + onDragStart.invoke(drag.position) + onVerticalDrag.invoke(drag, overSlop) + if ( + verticalDrag(drag.id) { + onVerticalDrag(it, it.positionChange().y) + it.consume() + } + ) { + onDragEnd() + } else { + onDragCancel() + } + } + } +} + @Preview(showBackground = true) @Composable @Suppress("UnusedPrivateMember") From 34340c3518f69d6a4f98fd040406d81f5ce62b99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:30:24 +0200 Subject: [PATCH 099/103] fix(deps): update dependency com.posthog:posthog-android to v3.39.0 (#6504) 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 3f16060207..3bc5cb31c3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -220,7 +220,7 @@ haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics -posthog = "com.posthog:posthog-android:3.37.0" +posthog = "com.posthog:posthog-android:3.39.0" sentry = "io.sentry:sentry-android:8.36.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.33.2" From b340e85f83fb3cd0465f7495d15715999ffa1988 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 1 Apr 2026 12:45:57 +0200 Subject: [PATCH 100/103] Add floating/sticky date badge in the timeline (#6496) * Add floating date indicator while scrolling the timeline (#6433) * Add `FeatureFlags.FloatingDateBadge`. This enables displaying the floating date badge in the timeline as you scroll. * Don't display the floating badge if the timeline isn't reversed. Otherwise, this will affect talkback users and break the existing navigation * Use `TimelineItem.formattedDate()` to get the date to display. Always try finding the closest one (usually it will be just the 1st one we try). * Align designs with iOS. Also fix shadows in fade animation by adding some paddings. * Update screenshots --------- Co-authored-by: Gianluca Iavicoli Co-authored-by: ElementBot --- .../features/messages/impl/MessagesView.kt | 6 + .../impl/timeline/TimelinePresenter.kt | 4 + .../messages/impl/timeline/TimelineState.kt | 1 + .../impl/timeline/TimelineStateProvider.kt | 2 + .../messages/impl/timeline/TimelineView.kt | 12 ++ .../timeline/components/FloatingDateBadge.kt | 144 ++++++++++++++++++ .../event/TimelineItemEventFactory.kt | 6 + .../impl/timeline/model/TimelineItem.kt | 8 + .../designsystem/theme/ColorAliases.kt | 3 + .../libraries/featureflag/api/FeatureFlags.kt | 9 +- ....components_FloatingDateBadge_Day_0_en.png | 3 + ...omponents_FloatingDateBadge_Night_0_en.png | 3 + 12 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/FloatingDateBadge.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Night_0_en.png diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 0caebea8d5..8e81ee74a7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role @@ -464,6 +465,9 @@ private fun MessagesViewContent( val scrollBehavior = PinnedMessagesBannerViewDefaults.rememberScrollBehavior( pinnedMessagesCount = (state.pinnedMessagesBannerState as? PinnedMessagesBannerState.Visible)?.pinnedMessagesCount() ?: 0, ) + val density = LocalDensity.current + var pinnedBannerHeightDp by remember { mutableStateOf(0.dp) } + TimelineView( state = state.timelineState, timelineProtectionState = state.timelineProtectionState, @@ -479,11 +483,13 @@ private fun MessagesViewContent( forceJumpToBottomVisibility = forceJumpToBottomVisibility, onJoinCallClick = onJoinCallClick, nestedScrollConnection = scrollBehavior.nestedScrollConnection, + floatingDateTopOffset = pinnedBannerHeightDp, ) if (state.timelineState.timelineMode !is Timeline.Mode.Thread) { AnimatedVisibility( visible = state.pinnedMessagesBannerState is PinnedMessagesBannerState.Visible && scrollBehavior.isVisible, + modifier = Modifier.onSizeChanged { pinnedBannerHeightDp = with(density) { it.height.toDp() } }, enter = expandVertically(), exit = shrinkVertically(), ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 12e4e0b1d1..8a7011552e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -149,6 +149,9 @@ class TimelinePresenter( val displayThreadSummaries by produceState(false) { value = featureFlagService.isFeatureEnabled(FeatureFlags.Threads) } + val displayFloatingDateBadge by produceState(false) { + value = featureFlagService.isFeatureEnabled(FeatureFlags.FloatingDateBadge) + } fun handleEvent(event: TimelineEvent) { when (event) { @@ -315,6 +318,7 @@ class TimelinePresenter( messageShieldDialogData = messageShieldDialogData.value, resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState, displayThreadSummaries = displayThreadSummaries, + displayFloatingDateBadge = displayFloatingDateBadge, eventSink = ::handleEvent, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt index 03f0083856..1869ad6906 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt @@ -34,6 +34,7 @@ data class TimelineState( val messageShieldDialogData: MessageShieldData?, val resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState, val displayThreadSummaries: Boolean, + val displayFloatingDateBadge: Boolean, val eventSink: (TimelineEvent) -> Unit, ) { private val lastTimelineEvent = timelineItems.firstOrNull { it is TimelineItem.Event } as? TimelineItem.Event diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt index 184acf1386..9840ac5107 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt @@ -56,6 +56,7 @@ fun aTimelineState( messageShield: MessageShield? = null, resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState = aResolveVerifiedUserSendFailureState(), displayThreadSummaries: Boolean = false, + displayFloatingDateBadge: Boolean = false, eventSink: (TimelineEvent) -> Unit = {}, ): TimelineState { val focusedEventId = timelineItems.filterIsInstance().getOrNull(focusedEventIndex)?.eventId @@ -75,6 +76,7 @@ fun aTimelineState( messageShieldDialogData = messageShield?.let { MessageShieldData(it) }, resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState, displayThreadSummaries = displayThreadSummaries, + displayFloatingDateBadge = displayFloatingDateBadge, eventSink = eventSink, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 08a7191f3f..0137b1736d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -47,10 +47,12 @@ import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.rememberNestedScrollInteropConnection import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.Dp 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.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureView +import io.element.android.features.messages.impl.timeline.components.FloatingDateBadgeOverlay import io.element.android.features.messages.impl.timeline.components.TimelineItemRow import io.element.android.features.messages.impl.timeline.components.toText import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories @@ -105,6 +107,7 @@ fun TimelineView( lazyListState: LazyListState = rememberLazyListState(), forceJumpToBottomVisibility: Boolean = false, nestedScrollConnection: NestedScrollConnection = rememberNestedScrollInteropConnection(), + floatingDateTopOffset: Dp = 0.dp, ) { fun clearFocusRequestState() { state.eventSink(TimelineEvent.ClearFocusRequestState) @@ -210,6 +213,15 @@ fun TimelineView( onJumpToLive = ::onJumpToLive, onFocusEventRender = ::onFocusEventRender, ) + + if (state.displayFloatingDateBadge && useReverseLayout) { + FloatingDateBadgeOverlay( + lazyListState = lazyListState, + timelineItems = state.timelineItems, + isLive = state.isLive, + topOffset = floatingDateTopOffset, + ) + } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/FloatingDateBadge.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/FloatingDateBadge.kt new file mode 100644 index 0000000000..996bb07b81 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/FloatingDateBadge.kt @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.components + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModel +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Surface +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.floatingDateBadgeBackground +import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collectLatest +import kotlin.time.Duration.Companion.milliseconds + +@Composable +internal fun BoxScope.FloatingDateBadgeOverlay( + lazyListState: LazyListState, + timelineItems: ImmutableList, + isLive: Boolean, + topOffset: Dp = 0.dp, +) { + // This needs to be a state to trigger a `derivedState` recalculation + val updatedTimelineItems by rememberUpdatedState(timelineItems) + + // Look for the last visible item with a timestamp, starting from the last visible item and going backwards until we find one or reach the start of the list + val lastVisibleItemWithTimestamp by remember { + derivedStateOf { + var index = lazyListState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: return@derivedStateOf null + while (index >= 0) { + when (val item = updatedTimelineItems.getOrNull(index)) { + is TimelineItem.Event -> return@derivedStateOf item + is TimelineItem.Virtual -> if (item.model is TimelineItemDaySeparatorModel) return@derivedStateOf item + is TimelineItem.GroupedEvents -> return@derivedStateOf item.events.firstOrNull() + null -> Unit + } + index-- + } + null + } + } + + // Store the formatted date so we recompute it lazily and can keep it around even if we need to dispose the badge because the timeline items changed + var formattedDate: String? by remember { mutableStateOf(null) } + // Update the formatted date when we have a new non-null timestamp + LaunchedEffect(lastVisibleItemWithTimestamp) { + lastVisibleItemWithTimestamp?.formattedDate()?.let { formattedDate = it } + } + + val isAtBottom by remember { + derivedStateOf { + lazyListState.firstVisibleItemIndex < 3 && isLive + } + } + + var isBadgeVisible by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { + snapshotFlow { lazyListState.isScrollInProgress } + .collectLatest { isScrolling -> + if (isScrolling) { + isBadgeVisible = true + } else { + delay(2000.milliseconds) + isBadgeVisible = false + } + } + } + + val showBadge = isBadgeVisible && !isAtBottom && formattedDate != null + + AnimatedVisibility( + visible = showBadge, + modifier = Modifier + .align(Alignment.TopCenter) + .padding(top = 8.dp + topOffset), + enter = fadeIn(animationSpec = tween(150)), + exit = fadeOut(animationSpec = tween(300)), + ) { + formattedDate?.let { dateText -> + FloatingDateBadge( + modifier = Modifier.padding(8.dp), + dateText = dateText, + ) + } + } +} + +@Composable +internal fun FloatingDateBadge( + dateText: String, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier, + shape = RoundedCornerShape(16.dp), + color = ElementTheme.colors.floatingDateBadgeBackground, + shadowElevation = 4.dp, + ) { + Text( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), + text = dateText, + style = ElementTheme.typography.fontBodyMdMedium, + color = ElementTheme.colors.textPrimary, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun FloatingDateBadgePreview() = ElementPreview { + Box(modifier = Modifier.padding(16.dp)) { + FloatingDateBadge(dateText = "March 9, 2026") + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt index 366c88157e..cf515a0b51 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt @@ -66,6 +66,11 @@ class TimelineItemEventFactory( timestamp = currentTimelineItem.event.timestamp, mode = DateFormatterMode.TimeOnly, ) + val sentDate = dateFormatter.format( + timestamp = currentTimelineItem.event.timestamp, + mode = DateFormatterMode.Day, + useRelative = true, + ) val senderAvatarData = AvatarData( id = currentSender.value, name = senderProfile.getDisambiguatedDisplayName(currentSender), @@ -108,6 +113,7 @@ class TimelineItemEventFactory( canBeRepliedTo = currentTimelineItem.event.canBeRepliedTo, sentTimeMillis = currentTimelineItem.event.timestamp, sentTime = sentTime, + sentDate = sentDate, groupPosition = groupPosition, reactionsState = currentTimelineItem.computeReactionsState(), readReceiptState = currentTimelineItem.computeReadReceiptState(roomMembers), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt index e169b10403..c9adba21da 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt @@ -15,6 +15,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent +import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModel import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.EventId @@ -59,6 +60,12 @@ sealed interface TimelineItem { is GroupedEvents -> "groupedEvent" } + fun formattedDate(): String? = when (this) { + is Event -> sentDate.takeIf { it.isNotEmpty() } + is Virtual -> (model as? TimelineItemDaySeparatorModel)?.formattedDate?.takeIf { it.isNotEmpty() } + is GroupedEvents -> null + } + data class Virtual( val id: UniqueId, val model: TimelineItemVirtualModel @@ -75,6 +82,7 @@ sealed interface TimelineItem { val content: TimelineItemEventContent, val sentTimeMillis: Long = 0L, val sentTime: String = "", + val sentDate: String = "", val isMine: Boolean = false, val isEditable: Boolean, val canBeRepliedTo: Boolean, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorAliases.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorAliases.kt index 06827fb218..8973e312ce 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorAliases.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorAliases.kt @@ -75,6 +75,9 @@ val SemanticColors.pinnedMessageBannerIndicator val SemanticColors.pinnedMessageBannerBorder get() = if (isLight) LightColorTokens.colorAlphaGray400 else DarkColorTokens.colorAlphaGray400 +val SemanticColors.floatingDateBadgeBackground + get() = if (isLight) bgCanvasDefault else bgSubtlePrimary + @PreviewsDayNight @Composable internal fun ColorAliasesPreview() = ElementPreview { 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 6cd9dec60c..9fe21a10c3 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 @@ -156,10 +156,17 @@ enum class FeatureFlags( ), ValidateNetworkWhenSchedulingNotificationFetching( key = "feature.validate_network_when_scheduling_notification_fetching", - title = "validate internet connectivity when scheduling notification fetching", + title = "Validate internet connectivity when scheduling notification fetching", description = "Only fetch events for push notifications when the device has internet connectivity. " + "Enabling this can be problematic in air-gapped environments.", defaultValue = { true }, isFinished = false, ), + FloatingDateBadge( + key = "feature.floating_date_badge", + title = "Display sticky date headers in the timeline", + description = "When scrolling, a sticky date badge will be displayed so you can easily know on which date the messages you're seeing were sent.", + defaultValue = { false }, + isFinished = false, + ), } diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Day_0_en.png new file mode 100644 index 0000000000..73693b6b51 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8109af7397a43f24a27b7c988f7b6bd23e555df038ff9a272068707796a60962 +size 8465 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Night_0_en.png new file mode 100644 index 0000000000..042d482550 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_FloatingDateBadge_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25ba3336d226da0fb5956750b02f389c59b81c93e6150d8fb17d5195fd161204 +size 7705 From f7c2adcdc43e2e5d73bebfee6424233c442d128f Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 1 Apr 2026 13:30:01 +0200 Subject: [PATCH 101/103] CI: yet another Maestro fix (#6505) * Fix the `assertSessionVerificationDisplayed.yaml` check * Previous 'Location' is now 'Share location' * We don't have a GPS location, so the text is 'Share selected location' * 'Create a new conversation' is now 'Create room' * Try adding a background logcat process * 'Sign out' is now 'Remove this device' * Adjust the logcat filtering so it silences everything that's not our app, otherwise the logs can get quite large --- .../scripts/maestro/maestro-local-with-screen-recording.sh | 3 +++ .maestro/tests/account/logout.yaml | 6 +++--- .../assertions/assertSessionVerificationDisplayed.yaml | 2 +- .maestro/tests/roomList/createAndDeleteDM.yaml | 2 +- .maestro/tests/roomList/createAndDeleteRoom.yaml | 2 +- .maestro/tests/roomList/timeline/messages/location.yaml | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh b/.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh index 51a968fdec..4ee021c316 100755 --- a/.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh +++ b/.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh @@ -19,6 +19,9 @@ adb install -r $1 echo "Starting the screen recording..." adb push .github/workflows/scripts/maestro/local-recording.sh /data/local/tmp/ adb shell "chmod +x /data/local/tmp/local-recording.sh" +mkdir -p ~/.maestro/tests +# Start logcat in the background and save the output to a file, use `org.matrix.rust.sdk` tag since the SDK handles the logging +adb logcat 'org.matrix.rust.sdk:D *:S' > ~/.maestro/tests/logcat.txt & adb shell "/data/local/tmp/local-recording.sh & echo \$! > /data/local/tmp/screenrecord_pid.txt" & set +e ~/.maestro/bin/maestro test .maestro/allTests.yaml diff --git a/.maestro/tests/account/logout.yaml b/.maestro/tests/account/logout.yaml index f27f5dada3..a276182825 100644 --- a/.maestro/tests/account/logout.yaml +++ b/.maestro/tests/account/logout.yaml @@ -2,14 +2,14 @@ appId: ${MAESTRO_APP_ID} --- - tapOn: id: "home_screen-settings" -- tapOn: "Sign out" +- tapOn: "Remove this device" - takeScreenshot: build/maestro/900-SignOutScreen - back -- tapOn: "Sign out" +- tapOn: "Remove this device" # Ensure cancel cancels - tapOn: id: "dialog-negative" -- tapOn: "Sign out" +- tapOn: "Remove this device" - tapOn: id: "dialog-positive" - runFlow: ../assertions/assertInitDisplayed.yaml diff --git a/.maestro/tests/assertions/assertSessionVerificationDisplayed.yaml b/.maestro/tests/assertions/assertSessionVerificationDisplayed.yaml index fff0fe7b32..d2160e0934 100644 --- a/.maestro/tests/assertions/assertSessionVerificationDisplayed.yaml +++ b/.maestro/tests/assertions/assertSessionVerificationDisplayed.yaml @@ -1,5 +1,5 @@ appId: ${MAESTRO_APP_ID} --- - extendedWaitUntil: - visible: "Confirm your identity" + visible: "Confirm your digital identity" timeout: 60000 diff --git a/.maestro/tests/roomList/createAndDeleteDM.yaml b/.maestro/tests/roomList/createAndDeleteDM.yaml index e80dc377b5..a6279151ea 100644 --- a/.maestro/tests/roomList/createAndDeleteDM.yaml +++ b/.maestro/tests/roomList/createAndDeleteDM.yaml @@ -1,7 +1,7 @@ appId: ${MAESTRO_APP_ID} --- # Purpose: Test the creation and deletion of a DM room. -- tapOn: "Create a new conversation or room" +- tapOn: "Create room" - tapOn: "Search for someone" - inputText: ${MAESTRO_INVITEE1_MXID} - tapOn: diff --git a/.maestro/tests/roomList/createAndDeleteRoom.yaml b/.maestro/tests/roomList/createAndDeleteRoom.yaml index d0b17133d5..b53066ccd5 100644 --- a/.maestro/tests/roomList/createAndDeleteRoom.yaml +++ b/.maestro/tests/roomList/createAndDeleteRoom.yaml @@ -1,7 +1,7 @@ appId: ${MAESTRO_APP_ID} --- # Purpose: Test the creation and deletion of a room -- tapOn: "Create a new conversation or room" +- tapOn: "Create room" - tapOn: "New room" - tapOn: "Add name…" - inputText: "aRoomName" diff --git a/.maestro/tests/roomList/timeline/messages/location.yaml b/.maestro/tests/roomList/timeline/messages/location.yaml index c9382bd30c..863a699fd9 100644 --- a/.maestro/tests/roomList/timeline/messages/location.yaml +++ b/.maestro/tests/roomList/timeline/messages/location.yaml @@ -2,6 +2,6 @@ appId: ${MAESTRO_APP_ID} --- - takeScreenshot: build/maestro/520-Timeline - tapOn: "Add attachment" -- tapOn: "Location" -- tapOn: "Share my location" +- tapOn: "Share location" +- tapOn: "Share selected location" - takeScreenshot: build/maestro/521-Timeline From 111272c524404ef1020840162046eb24bf7822fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 1 Apr 2026 13:37:57 +0200 Subject: [PATCH 102/103] Setting version for the release 26.04.0 --- plugins/src/main/kotlin/Versions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index 618587d2bd..4fbc3fb20c 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -39,13 +39,13 @@ private const val versionYear = 26 * Month of the version on 2 digits. Value must be in [1,12]. * Do not update this value. it is updated by the release script. */ -private const val versionMonth = 3 +private const val versionMonth = 4 /** * Release number in the month. Value must be in [0,99]. * Do not update this value. it is updated by the release script. */ -private const val versionReleaseNumber = 4 +private const val versionReleaseNumber = 0 object Versions { /** From 865fccc8f6a1fbab59d7243193d0d10cad627474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 1 Apr 2026 13:42:04 +0200 Subject: [PATCH 103/103] Adding fastlane file for version 26.04.0 --- fastlane/metadata/android/en-US/changelogs/202604000.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/202604000.txt diff --git a/fastlane/metadata/android/en-US/changelogs/202604000.txt b/fastlane/metadata/android/en-US/changelogs/202604000.txt new file mode 100644 index 0000000000..26b1479a0d --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/202604000.txt @@ -0,0 +1,2 @@ +Main changes in this version: bug fixes for crashes from the SDK and notifications and UI improvements. +Full changelog: https://github.com/element-hq/element-x-android/releases